styled-components-to-stylex-codemod 0.0.40 → 0.0.41

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,4 +1,4 @@
1
- import { o as resolveBarrelReExportBinding, r as findImportSource } from "./extract-external-interface-DbzIPO0Z.mjs";
1
+ import { o as resolveBarrelReExportBinding, r as findImportSource } from "./extract-external-interface-B61N1a6q.mjs";
2
2
  //#region src/internal/prepass/compute-leaf-set.ts
3
3
  /**
4
4
  * Computes which styled-component bindings are "leaves" for leaves-only mode:
@@ -348,7 +348,7 @@ function getFileExportsRe(name) {
348
348
  }
349
349
  return re;
350
350
  }
351
- function fileImportsFrom(usageSrc, usageFile, name, defFile, resolve) {
351
+ function fileImportsFrom(usageSrc, usageFile, name, defFile, resolve, read) {
352
352
  const [namedRe, defaultRe] = getFileImportsFromRes(name);
353
353
  namedRe.lastIndex = 0;
354
354
  defaultRe.lastIndex = 0;
@@ -358,11 +358,17 @@ function fileImportsFrom(usageSrc, usageFile, name, defFile, resolve) {
358
358
  const specifier = match[1];
359
359
  if (!specifier) continue;
360
360
  const resolved = resolve(specifier, usageFile);
361
- if (resolved && path.resolve(resolved) === path.resolve(defFile)) return true;
361
+ if (resolved && importCanReferenceDefinition(resolved, name, defFile, resolve, read)) return true;
362
362
  if (specifier.endsWith(stem) || specifier.endsWith(`${parent}/${stem}`) || specifier.endsWith(parent)) return true;
363
363
  }
364
364
  return false;
365
365
  }
366
+ function importCanReferenceDefinition(resolvedImport, name, defFile, resolve, read) {
367
+ if (path.resolve(resolvedImport) === path.resolve(defFile)) return true;
368
+ if (!read) return false;
369
+ const reExportedFile = resolveBarrelReExport(resolvedImport, name, resolve, read);
370
+ return reExportedFile !== null && path.resolve(reExportedFile) === path.resolve(defFile);
371
+ }
366
372
  const fileImportsFromReCache = /* @__PURE__ */ new Map();
367
373
  function getFileImportsFromRes(name) {
368
374
  let cached = fileImportsFromReCache.get(name);
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as CollectedWarning, c as MarkerFileContext, l as defineAdapter, n as TransformMode, o as AdapterInput, s as ImportSource } from "./transform-types-DUT5eSAm.mjs";
1
+ import { a as CollectedWarning, c as MarkerFileContext, l as defineAdapter, n as TransformMode, o as AdapterInput, s as ImportSource } from "./transform-types-Bl-oPkjl.mjs";
2
2
 
3
3
  //#region src/run.d.ts
4
4
  interface RunTransformOptions {
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { o as assertValidAdapterInput, r as defineAdapter, s as describeValue, t as mergeMarkerDeclarations } from "./merge-markers-BC5YNB7D.mjs";
2
- import { a as resolveBarrelReExport, s as Logger } from "./extract-external-interface-DbzIPO0Z.mjs";
3
- import { r as extractStyledDefBasesFromSource } from "./compute-leaf-set-C-xis90s.mjs";
1
+ import { a as defineAdapter, c as assertValidAdapterInput, l as describeValue, r as mergeMarkerDeclarations, t as detectExportedComponentSxProp } from "./wrapped-component-interface-yvZ-_HMO.mjs";
2
+ import { a as resolveBarrelReExport, s as Logger } from "./extract-external-interface-B61N1a6q.mjs";
3
+ import { r as extractStyledDefBasesFromSource } from "./compute-leaf-set-Be5Cgxnr.mjs";
4
4
  import { n as toRealPath } from "./path-utils-BIpoL4Ue.mjs";
5
5
  import jscodeshift from "jscodeshift";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -149,7 +149,7 @@ async function runTransform(options) {
149
149
  const { createModuleResolver } = await import("./resolve-imports-DgSAddIF.mjs").then((n) => n.n);
150
150
  const sharedResolver = createModuleResolver();
151
151
  filePaths = orderFilesByLocalImportDependencies(filePaths, sharedResolver, toRealPath);
152
- const { runPrepass } = await import("./run-prepass-jnJbdfxU.mjs");
152
+ const { runPrepass } = await import("./run-prepass-J4t6jkCI.mjs");
153
153
  const absoluteFiles = filePaths.map((f) => resolve(f));
154
154
  const absoluteConsumers = consumerFilePaths.map((f) => resolve(f));
155
155
  let prepassResult;
@@ -180,6 +180,7 @@ async function runTransform(options) {
180
180
  };
181
181
  }
182
182
  const transformedFiles = /* @__PURE__ */ new Set();
183
+ const transformedFileSources = /* @__PURE__ */ new Map();
183
184
  const crossFilePrepassResult = {
184
185
  ...prepassResult.crossFileInfo,
185
186
  transformedFiles
@@ -243,12 +244,16 @@ async function runTransform(options) {
243
244
  if (!resolvedImport) return;
244
245
  const resolvedPath = toRealPath(resolvedImport);
245
246
  const definitionSourcePath = resolveExistingSourcePath(resolveBarrelReExport(resolvedPath, ctx.importedName, prepassResolve, cachedRead) ?? resolvedPath);
246
- if (!transformedFiles.has(toRealPath(definitionSourcePath))) return;
247
247
  const autoInterfaceNames = ctx.importedName === "default" ? [ctx.localName, ctx.importedName] : [ctx.importedName];
248
248
  const styledDefinitionNames = getStyledDefinitionNames(definitionSourcePath);
249
249
  const sourceComponentNames = ctx.importedName === "default" ? [ctx.localName, getDefaultExportedName(definitionSourcePath)].filter((name) => typeof name === "string") : [ctx.importedName];
250
- const definitionSource = cachedRead(definitionSourcePath);
251
- if (!(definitionSource.includes("sx?: stylex.StyleXStyles") && sourceComponentNames.some((name) => definitionSource.includes(name))) && !sourceComponentNames.some((name) => styledDefinitionNames.has(name))) return;
250
+ if (sourceComponentNames.some((name) => detectExportedComponentSxProp({
251
+ absolutePath: definitionSourcePath,
252
+ componentName: name,
253
+ sourceOverrides: transformedFileSources
254
+ }))) return { acceptsSx: true };
255
+ if (!transformedFiles.has(toRealPath(definitionSourcePath))) return;
256
+ if (!sourceComponentNames.some((name) => styledDefinitionNames.has(name))) return;
252
257
  return autoInterfaceNames.map((name) => lookupAutoExternalInterface(definitionSourcePath, name)).find((result) => result !== void 0)?.styles ? { acceptsSx: true } : void 0;
253
258
  }
254
259
  };
@@ -297,7 +302,7 @@ async function runTransform(options) {
297
302
  sidecarFiles,
298
303
  bridgeResults,
299
304
  transformedFiles,
300
- transformedFileSources: /* @__PURE__ */ new Map(),
305
+ transformedFileSources,
301
306
  transientPropRenames,
302
307
  allowPartialMigration: options.allowPartialMigration ?? (leavesOnly ? true : false),
303
308
  transformMode: leavesOnly ? "leavesOnly" : options.transformMode ?? "all",
@@ -1,5 +1,5 @@
1
- import { a as resolveBarrelReExport, n as fileImportsFrom, r as findImportSource, s as Logger, t as fileExports } from "./extract-external-interface-DbzIPO0Z.mjs";
2
- import { n as extractStyledDefBasesFromAstProgram, r as extractStyledDefBasesFromSource, t as computeGlobalLeafKeys } from "./compute-leaf-set-C-xis90s.mjs";
1
+ import { a as resolveBarrelReExport, n as fileImportsFrom, o as resolveBarrelReExportBinding, r as findImportSource, s as Logger, t as fileExports } from "./extract-external-interface-B61N1a6q.mjs";
2
+ import { n as extractStyledDefBasesFromAstProgram, r as extractStyledDefBasesFromSource, t as computeGlobalLeafKeys } from "./compute-leaf-set-Be5Cgxnr.mjs";
3
3
  import { r as escapeRegex } from "./string-utils-DD9wdRHW.mjs";
4
4
  import { a as PLACEHOLDER_RE, i as readStaticJsxLiteral, n as createComponentPropUsageInfo, r as mergeComponentPropUsage, t as KNOWN_NON_ELEMENT_PROPS } from "./prop-usage-D6ZiDfzz.mjs";
5
5
  import { t as isSelectorContext } from "./selector-context-heuristic-6_jSRGkZ.mjs";
@@ -229,6 +229,10 @@ function buildImportMapFromNodes(importNodes) {
229
229
  source: sourceValue,
230
230
  importedName: "default"
231
231
  });
232
+ else if (spec.type === "ImportNamespaceSpecifier") map.set(localName, {
233
+ source: sourceValue,
234
+ importedName: "*"
235
+ });
232
236
  else if (spec.type === "ImportSpecifier") {
233
237
  const importedName = getNodeName(spec.imported) ?? localName;
234
238
  map.set(localName, {
@@ -533,14 +537,19 @@ async function runPrepass(options) {
533
537
  const rgHits = createExternalInterface ? rgClassNameStyleFilter(uniqueAllFiles) : void 0;
534
538
  const jsxHits = rgJsxComponentFilter(uniqueAllFiles);
535
539
  const scanAndRecord = (filePath, source) => {
536
- if (createExternalInterface) for (const result of scanConsumerProps(source, allStyledNames)) {
537
- addToSetMap(classNameStyleUsages, result.name, filePath);
538
- if (result.className) addToSetMap(classNameUsages, result.name, filePath);
539
- if (result.style) addToSetMap(styleUsages, result.name, filePath);
540
- if (result.elementProps) addToSetMap(elementPropUsages, result.name, filePath);
541
- if (result.spreadProps) addToSetMap(spreadPropUsages, result.name, filePath);
540
+ const jsxScan = scanConsumerJsxUsages(filePath, source, allStyledNames, parser);
541
+ if (createExternalInterface) for (const result of jsxScan.propResults) {
542
+ const usage = {
543
+ filePath,
544
+ importSource: result.importSource
545
+ };
546
+ if (result.className || result.style || result.spreadProps) addConsumerUsage(classNameStyleUsages, result.name, usage);
547
+ if (result.className) addConsumerUsage(classNameUsages, result.name, usage);
548
+ if (result.style) addConsumerUsage(styleUsages, result.name, usage);
549
+ if (result.elementProps) addConsumerUsage(elementPropUsages, result.name, usage);
550
+ if (result.spreadProps) addConsumerUsage(spreadPropUsages, result.name, usage);
542
551
  }
543
- for (const usage of scanConsumerStaticPropUsages(filePath, source, allStyledNames, parser)) {
552
+ for (const usage of jsxScan.staticPropUsages) {
544
553
  const entries = propUsageCandidates.get(usage.name) ?? [];
545
554
  entries.push(usage);
546
555
  propUsageCandidates.set(usage.name, entries);
@@ -584,7 +593,7 @@ async function runPrepass(options) {
584
593
  }
585
594
  return entry;
586
595
  };
587
- const matchUsagesToDefinitions = (usages, field) => {
596
+ const matchUsageFilesToDefinitions = (usages, field) => {
588
597
  if (usages.size === 0) return;
589
598
  for (const [defFile, names] of styledDefFiles) {
590
599
  const defSrc = cachedRead(defFile);
@@ -596,20 +605,32 @@ async function runPrepass(options) {
596
605
  ensure(defFile, name)[field] = true;
597
606
  continue;
598
607
  }
599
- for (const usageFile of usageFiles) if (fileImportsFrom(cachedRead(usageFile), usageFile, name, defFile, resolve$1)) {
608
+ for (const usageFile of usageFiles) if (fileImportsFrom(cachedRead(usageFile), usageFile, name, defFile, resolve$1, cachedRead)) {
600
609
  ensure(defFile, name)[field] = true;
601
610
  break;
602
611
  }
603
612
  }
604
613
  }
605
614
  };
606
- matchUsagesToDefinitions(asUsages, "as");
607
- matchUsagesToDefinitions(refUsages, "ref");
608
- matchUsagesToDefinitions(classNameStyleUsages, "styles");
609
- matchUsagesToDefinitions(classNameUsages, "className");
610
- matchUsagesToDefinitions(styleUsages, "style");
611
- matchUsagesToDefinitions(elementPropUsages, "elementProps");
612
- matchUsagesToDefinitions(spreadPropUsages, "spreadProps");
615
+ const matchConsumerUsagesToDefinitions = (usages, field) => {
616
+ if (usages.size === 0) return;
617
+ for (const [defFile, names] of styledDefFiles) {
618
+ const defSrc = cachedRead(defFile);
619
+ for (const name of names) {
620
+ const usageRefs = usages.get(name);
621
+ if (!usageRefs) continue;
622
+ if (!fileExports(defSrc, name)) continue;
623
+ if (usageRefs.some((usageRef) => consumerUsageReferencesDefinition(usageRef, name, defFile, cachedRead, resolve$1))) ensure(defFile, name)[field] = true;
624
+ }
625
+ }
626
+ };
627
+ matchUsageFilesToDefinitions(asUsages, "as");
628
+ matchUsageFilesToDefinitions(refUsages, "ref");
629
+ matchConsumerUsagesToDefinitions(classNameStyleUsages, "styles");
630
+ matchConsumerUsagesToDefinitions(classNameUsages, "className");
631
+ matchConsumerUsagesToDefinitions(styleUsages, "style");
632
+ matchConsumerUsagesToDefinitions(elementPropUsages, "elementProps");
633
+ matchConsumerUsagesToDefinitions(spreadPropUsages, "spreadProps");
613
634
  {
614
635
  const seen = /* @__PURE__ */ new Set();
615
636
  for (const { file, name } of styledCallUsages) {
@@ -759,8 +780,27 @@ function importTextMentionsIdentifier(importText, identifier) {
759
780
  }
760
781
  return re.test(importText);
761
782
  }
762
- /** Quick pre-check: does this source mention className or style in a JSX prop context? */
763
- const CLASSNAME_STYLE_QUICK_RE = /\b(className|style)\s*[={]/;
783
+ function addConsumerUsage(map, name, usage) {
784
+ const entries = map.get(name) ?? [];
785
+ if (!entries.some((entry) => entry.filePath === usage.filePath && entry.importSource === usage.importSource)) {
786
+ entries.push(usage);
787
+ map.set(name, entries);
788
+ }
789
+ }
790
+ function consumerUsageReferencesDefinition(usage, name, defFile, cachedRead, resolve) {
791
+ if (usage.importSource) return importSourceReferencesDefinition(usage.importSource, usage.filePath, name, defFile, resolve, cachedRead);
792
+ if (usage.filePath === defFile) return true;
793
+ return fileImportsFrom(cachedRead(usage.filePath), usage.filePath, name, defFile, resolve, cachedRead);
794
+ }
795
+ function importSourceReferencesDefinition(importSource, usageFile, name, defFile, resolve$2, cachedRead) {
796
+ const resolved = resolve$2(importSource, usageFile);
797
+ if (!resolved) return false;
798
+ if (resolve(resolved) === resolve(defFile)) return true;
799
+ const binding = resolveBarrelReExportBinding(resolved, name, resolve$2, cachedRead);
800
+ return binding !== null && resolve(binding.filePath) === resolve(defFile);
801
+ }
802
+ /** Quick pre-check: does this source mention JSX that might use external consumer props? */
803
+ const CONSUMER_PROPS_QUICK_RE = /<(?:[A-Z]|[A-Za-z_$][A-Za-z0-9_$]*\.)|\b(className|style)\s*[={]|\{\.\.\./;
764
804
  /** Matches `import { Original as Local, ... }` — captures original and local names. */
765
805
  const IMPORT_ALIAS_ENTRY_RE = /\b(\w+)\s+as\s+(\w+)/g;
766
806
  /**
@@ -783,99 +823,166 @@ function buildLocalToImportedMap(source) {
783
823
  /**
784
824
  * Scan source for JSX usage of specific components with className, style,
785
825
  * element-specific props, or JSX spread.
786
- * Uses a two-step approach: first quick-checks for className/style keywords,
787
- * then scans JSX open tags to match component names — avoids building a huge
788
- * alternation regex when there are hundreds of component names.
789
- * Handles aliased imports (e.g., `import { Alert as MyAlert }`) by resolving
790
- * local tag names back to their original exported names.
826
+ * Uses the prepass parser so comments and string literals cannot be mistaken
827
+ * for real JSX consumers.
791
828
  */
792
- function scanConsumerProps(source, componentNames) {
793
- if (!CLASSNAME_STYLE_QUICK_RE.test(source)) return [];
794
- let aliasMap;
795
- const resultMap = /* @__PURE__ */ new Map();
796
- for (const m of source.matchAll(/<([A-Z][A-Za-z0-9]*)\b([^<>]*?)(?:\/>|>)/gs)) {
797
- const tagName = m[1];
798
- const attrText = m[2] ?? "";
799
- if (!tagName) continue;
800
- let resolvedName;
801
- if (componentNames.has(tagName)) resolvedName = tagName;
802
- else {
803
- aliasMap ??= buildLocalToImportedMap(source);
804
- const originalName = aliasMap.get(tagName);
805
- if (originalName && componentNames.has(originalName)) resolvedName = originalName;
806
- }
807
- if (!resolvedName) continue;
808
- if (!/\b(?:className|style)\s*[={]/.test(attrText) && !/\{\.\.\./.test(attrText)) continue;
809
- let entry = resultMap.get(resolvedName);
810
- if (!entry) {
811
- entry = {
812
- name: resolvedName,
813
- className: false,
814
- style: false,
815
- elementProps: false,
816
- spreadProps: false
817
- };
818
- resultMap.set(resolvedName, entry);
819
- }
820
- if (/\bclassName\s*[={]/.test(attrText)) entry.className = true;
821
- if (/\bstyle\s*[={]/.test(attrText)) entry.style = true;
822
- if (/\{\.\.\./.test(attrText)) entry.spreadProps = true;
823
- for (const pm of attrText.matchAll(/\b([a-z][a-zA-Z-]*)(?=\s*[={]|\s+[a-z]|\s*$)/gi)) {
824
- const propName = pm[1];
825
- if (!KNOWN_NON_ELEMENT_PROPS.has(propName) && !propName.startsWith("$")) {
826
- entry.elementProps = true;
827
- break;
828
- }
829
- }
830
- }
831
- return [...resultMap.values()];
832
- }
833
- function scanConsumerStaticPropUsages(filePath, source, componentNames, parser) {
834
- if (!/<[A-Z]/.test(source)) return [];
829
+ function scanConsumerJsxUsages(filePath, source, componentNames, parser) {
830
+ if (!CONSUMER_PROPS_QUICK_RE.test(source)) return {
831
+ propResults: [],
832
+ staticPropUsages: []
833
+ };
835
834
  let ast;
836
835
  try {
837
836
  ast = parser.parse(source);
838
837
  } catch {
839
- return [];
838
+ return {
839
+ propResults: scanConsumerPropsRegexFallback(source, componentNames),
840
+ staticPropUsages: []
841
+ };
840
842
  }
841
843
  const importNodes = [];
842
844
  const jsxOpenings = [];
843
845
  walkForImportsAndJsxOpenings(ast.program ?? ast, importNodes, jsxOpenings);
844
846
  const importMap = buildImportMapFromNodes(importNodes);
845
- const usages = [];
847
+ const resultMap = /* @__PURE__ */ new Map();
848
+ const staticPropUsages = [];
846
849
  for (const opening of jsxOpenings) {
847
- const tagName = getJsxOpeningIdentifierName(opening.name);
848
- if (!tagName) continue;
849
- const importEntry = importMap.get(tagName);
850
- const resolvedName = componentNames.has(tagName) ? tagName : importEntry && componentNames.has(importEntry.importedName) ? importEntry.importedName : void 0;
851
- if (!resolvedName) continue;
852
- const props = {};
853
- let hasSpread = false;
854
- for (const attr of opening.attributes ?? []) {
855
- if (!attr) continue;
856
- if (attr.type === "JSXSpreadAttribute") {
857
- hasSpread = true;
858
- continue;
850
+ const resolvedComponent = resolveJsxOpeningComponent(opening.name, importMap, componentNames);
851
+ if (!resolvedComponent) continue;
852
+ const openingUsage = readConsumerOpeningUsage(opening);
853
+ const { externalProps } = openingUsage;
854
+ if (externalProps.className || externalProps.style || externalProps.spreadProps || externalProps.elementProps) {
855
+ const key = `${resolvedComponent.name}\0${resolvedComponent.importSource ?? ""}`;
856
+ let entry = resultMap.get(key);
857
+ if (!entry) {
858
+ entry = {
859
+ name: resolvedComponent.name,
860
+ importSource: resolvedComponent.importSource,
861
+ className: false,
862
+ style: false,
863
+ elementProps: false,
864
+ spreadProps: false
865
+ };
866
+ resultMap.set(key, entry);
859
867
  }
860
- if (attr.type !== "JSXAttribute") continue;
861
- const propName = getJsxAttributeName(attr.name);
862
- if (!propName || KNOWN_NON_ELEMENT_PROPS.has(propName)) continue;
868
+ entry.className ||= externalProps.className;
869
+ entry.style ||= externalProps.style;
870
+ entry.spreadProps ||= externalProps.spreadProps;
871
+ entry.elementProps ||= externalProps.elementProps;
872
+ }
873
+ staticPropUsages.push({
874
+ name: resolvedComponent.name,
875
+ filePath,
876
+ importSource: resolvedComponent.importSource,
877
+ usage: openingUsage.staticUsage
878
+ });
879
+ }
880
+ return {
881
+ propResults: [...resultMap.values()],
882
+ staticPropUsages
883
+ };
884
+ }
885
+ function resolveJsxOpeningComponent(name, importMap, componentNames) {
886
+ const localName = getJsxOpeningIdentifierName(name);
887
+ if (localName) {
888
+ if (componentNames.has(localName)) return { name: localName };
889
+ const importEntry = importMap.get(localName);
890
+ return importEntry && componentNames.has(importEntry.importedName) ? {
891
+ name: importEntry.importedName,
892
+ importSource: importEntry.source
893
+ } : void 0;
894
+ }
895
+ const member = getJsxMemberNameParts(name);
896
+ if (!member || !componentNames.has(member.propertyName)) return;
897
+ const importEntry = importMap.get(member.objectName);
898
+ return importEntry?.importedName === "*" ? {
899
+ name: member.propertyName,
900
+ importSource: importEntry.source
901
+ } : void 0;
902
+ }
903
+ function readConsumerOpeningUsage(opening) {
904
+ const externalProps = {
905
+ className: false,
906
+ style: false,
907
+ elementProps: false,
908
+ spreadProps: false
909
+ };
910
+ const props = {};
911
+ let hasSpread = false;
912
+ for (const attr of opening.attributes ?? []) {
913
+ if (!attr) continue;
914
+ if (attr.type === "JSXSpreadAttribute") {
915
+ externalProps.spreadProps = true;
916
+ hasSpread = true;
917
+ continue;
918
+ }
919
+ if (attr.type !== "JSXAttribute") continue;
920
+ const propName = getJsxAttributeName(attr.name);
921
+ if (!propName) continue;
922
+ if (propName === "className") externalProps.className = true;
923
+ else if (propName === "style") externalProps.style = true;
924
+ else if (isElementConsumerProp(propName)) externalProps.elementProps = true;
925
+ if (!KNOWN_NON_ELEMENT_PROPS.has(propName)) {
863
926
  const value = readStaticJsxLiteral(attr);
864
927
  props[propName] = value === void 0 ? { kind: "unknown" } : {
865
928
  kind: "static",
866
929
  value
867
930
  };
868
931
  }
869
- usages.push({
870
- name: resolvedName,
871
- filePath,
872
- usage: {
873
- props,
874
- hasSpread
932
+ }
933
+ return {
934
+ externalProps,
935
+ staticUsage: {
936
+ props,
937
+ hasSpread
938
+ }
939
+ };
940
+ }
941
+ function isElementConsumerProp(propName) {
942
+ return !KNOWN_NON_ELEMENT_PROPS.has(propName) && !propName.startsWith("$");
943
+ }
944
+ function scanConsumerPropsRegexFallback(source, componentNames) {
945
+ const resultMap = /* @__PURE__ */ new Map();
946
+ let aliasMap;
947
+ for (const match of source.matchAll(/<([A-Z][A-Za-z0-9]*)\b([^<>]*?)(?:\/>|>)/gs)) {
948
+ const tagName = match[1];
949
+ const attrText = match[2] ?? "";
950
+ if (!tagName) continue;
951
+ const resolvedName = componentNames.has(tagName) ? tagName : (() => {
952
+ aliasMap ??= buildLocalToImportedMap(source);
953
+ const originalName = aliasMap.get(tagName);
954
+ return originalName && componentNames.has(originalName) ? originalName : void 0;
955
+ })();
956
+ if (!resolvedName) continue;
957
+ const className = /\bclassName\s*[={]/.test(attrText);
958
+ const style = /\bstyle\s*[={]/.test(attrText);
959
+ const spreadProps = /\{\.\.\./.test(attrText);
960
+ let elementProps = false;
961
+ for (const propMatch of attrText.matchAll(/\b([a-z][a-zA-Z-]*)(?=\s*[={]|\s+[a-z]|\s*$)/gi)) {
962
+ const propName = propMatch[1];
963
+ if (isElementConsumerProp(propName)) {
964
+ elementProps = true;
965
+ break;
875
966
  }
876
- });
967
+ }
968
+ if (!className && !style && !spreadProps && !elementProps) continue;
969
+ let entry = resultMap.get(resolvedName);
970
+ if (!entry) {
971
+ entry = {
972
+ name: resolvedName,
973
+ className: false,
974
+ style: false,
975
+ elementProps: false,
976
+ spreadProps: false
977
+ };
978
+ resultMap.set(resolvedName, entry);
979
+ }
980
+ entry.className ||= className;
981
+ entry.style ||= style;
982
+ entry.spreadProps ||= spreadProps;
983
+ entry.elementProps ||= elementProps;
877
984
  }
878
- return usages;
985
+ return [...resultMap.values()];
879
986
  }
880
987
  function buildPropUsageByFile(args) {
881
988
  const { styledDefFiles, propUsageCandidates, cachedRead, resolve, toRealPath } = args;
@@ -886,8 +993,7 @@ function buildPropUsageByFile(args) {
886
993
  const candidates = propUsageCandidates.get(name);
887
994
  if (!candidates || !fileExports(defSrc, name)) continue;
888
995
  for (const candidate of candidates) {
889
- const usageFile = candidate.filePath;
890
- if (usageFile !== defFile && !fileImportsFrom(cachedRead(usageFile), usageFile, name, defFile, resolve)) continue;
996
+ if (!consumerUsageReferencesDefinition(candidate, name, defFile, cachedRead, resolve)) continue;
891
997
  mergeComponentPropUsage(getOrCreateComponentPropUsage(getOrCreatePropUsageFileMap(propUsageByFile, toRealPath(defFile)), name), candidate.usage);
892
998
  }
893
999
  }
@@ -917,10 +1023,7 @@ function walkForImportsAndJsxOpenings(node, imports, jsxOpenings) {
917
1023
  imports.push(n);
918
1024
  return;
919
1025
  }
920
- if (n.type === "JSXOpeningElement") {
921
- jsxOpenings.push(n);
922
- return;
923
- }
1026
+ if (n.type === "JSXOpeningElement") jsxOpenings.push(n);
924
1027
  for (const key of Object.keys(n)) {
925
1028
  if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "leadingComments" || key === "trailingComments") continue;
926
1029
  const val = n[key];
@@ -933,6 +1036,16 @@ function getJsxOpeningIdentifierName(name) {
933
1036
  if (name.type === "JSXIdentifier" && typeof name.name === "string") return name.name;
934
1037
  return null;
935
1038
  }
1039
+ function getJsxMemberNameParts(name) {
1040
+ if (!name || name.type !== "JSXMemberExpression") return null;
1041
+ const object = name.object;
1042
+ const property = name.property;
1043
+ if (object?.type !== "JSXIdentifier" || typeof object.name !== "string" || property?.type !== "JSXIdentifier" || typeof property.name !== "string") return null;
1044
+ return {
1045
+ objectName: object.name,
1046
+ propertyName: property.name
1047
+ };
1048
+ }
936
1049
  function getJsxAttributeName(name) {
937
1050
  if (!name) return null;
938
1051
  if (name.type === "JSXIdentifier" && typeof name.name === "string") return name.name;
@@ -967,7 +1080,7 @@ function rgClassNameStyleFilter(files) {
967
1080
  return;
968
1081
  }
969
1082
  }
970
- /** Use ripgrep to find files with PascalCase JSX tags. */
1083
+ /** Use ripgrep to find files with PascalCase or namespace JSX tags. */
971
1084
  function rgJsxComponentFilter(files) {
972
1085
  const dirs = deduplicateParentDirs(files);
973
1086
  if (dirs.length === 0) return;
@@ -982,7 +1095,7 @@ function rgJsxComponentFilter(files) {
982
1095
  "*.mjs",
983
1096
  "*.cjs"
984
1097
  ].map((glob) => `--glob ${shellQuote(glob)}`).join(" ");
985
- const output = execSync(`rg -l ${shellQuote(String.raw`<[A-Z]`)} ${globArgs} ${dirs.map(shellQuote).join(" ")}`, {
1098
+ const output = execSync(`rg -l ${shellQuote(String.raw`<([A-Z]|[A-Za-z_$][A-Za-z0-9_$]*\.)`)} ${globArgs} ${dirs.map(shellQuote).join(" ")}`, {
986
1099
  encoding: "utf-8",
987
1100
  maxBuffer: 10 * 1024 * 1024
988
1101
  });
@@ -371,7 +371,7 @@ type ResolveBaseComponentStaticValue = string | number | boolean;
371
371
  interface ResolveBaseComponentContext {
372
372
  /**
373
373
  * Import source for the wrapped base component.
374
- * - package import: "@linear/orbiter/components/Flex"
374
+ * - package import: "@acme/design-system/components/Flex"
375
375
  * - relative import: resolved absolute path
376
376
  */
377
377
  importSource: string;
@@ -921,7 +921,7 @@ declare function defineAdapter<T extends AdapterInput>(adapter: T): T;
921
921
  //#endregion
922
922
  //#region src/internal/logger.d.ts
923
923
  type Severity = "info" | "warning" | "error";
924
- type WarningType = "`css` helper function switch must return css templates in all branches" | "`css` helper usage as a function call (css(...)) is not supported" | "`css` helper used outside of a styled component template cannot be statically transformed" | "Adapter helper call in border interpolation did not resolve to a single CSS value" | "Adapter resolveCall returned an unparseable styles expression" | "Adapter resolveCall returned an unparseable value expression" | "Adapter resolveCall returned StyleX styles for helper call where a CSS value was expected" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolveBaseComponent threw an error" | "Adapter resolved StyleX styles cannot be applied under nested selectors/at-rules" | "Adapter resolved StyleX styles inside pseudo selector but did not provide cssText for property expansion — add cssText to resolveCall result to enable pseudo-wrapping" | 'Adapter resolveCall cssText could not be parsed as CSS declarations — expected semicolon-separated property: value pairs (e.g. "white-space: nowrap; overflow: hidden;")' | "Adapter resolveValue returned an unparseable value expression" | "Adapter resolveValue returned undefined for imported value" | "Arrow function: body is not a recognized pattern (expected ternary, logical, call, or member expression)" | "Arrow function: conditional branches could not be resolved to static or theme values" | "Arrow function: helper call body is not supported" | "Arrow function: indexed theme lookup pattern not matched" | "Arrow function: logical expression pattern not supported" | "Arrow function: prop access cannot be converted to style function for this CSS property" | "Arrow function: theme access path could not be resolved" | "Component selectors like `${OtherComponent}:hover &` are not directly representable in StyleX. Manual refactor is required" | "Conditional `css` block: !important is not supported in StyleX" | "Conditional `css` block: @-rules (e.g., @media, @supports) are not supported" | "CSS block contains unsupported at-rule (only @media and @container are supported; @supports, etc. require manual handling)" | "Conditional `css` block: dynamic interpolation could not be resolved to a single component prop" | "Conditional `css` block: failed to parse expression" | "Conditional `css` block: missing CSS property name" | "Conditional `css` block: missing interpolation expression" | "Conditional `css` block: mixed static/dynamic values with non-theme expressions cannot be safely transformed" | "Conditional `css` block: multiple interpolation slots in a single property value" | "Conditional `css` block: ternary branch value could not be resolved (imported values require adapter support)" | "Conditional `css` block: ternary expressions inside pseudo selectors are not supported" | "Conditional `css` block: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "Resolved border helper value could not be expanded to longhand properties" | "Resolved conditional border variant could not be expanded to longhand properties" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "Failed to parse theme expressions" | "Heterogeneous background values (mix of gradients and colors) not currently supported" | "Higher-order styled factory wrappers (e.g. hoc(styled)) are not supported" | "Imported CSS helper mixins: cannot determine inherited properties for correct pseudo selector handling" | "Local helper function returns CSS that cannot be decomposed into individual properties" | "Local helper function computes CSS values that cannot be statically traced to the component prop" | "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand" | "Styled-components specificity hacks like `&&` / `&&&` are not representable in StyleX" | "Theme-dependent block-level conditional could not be fully resolved (branches may contain dynamic interpolations)" | "Theme-dependant call expression could not be resolved (e.g. theme helper calls like theme.highlight() are not supported)" | "Theme value with fallback (props.theme.X ?? / || default) cannot be resolved statically — use adapter.resolveValue to map theme paths to StyleX tokens" | "Theme-dependent nested prop access requires a project-specific theme source (e.g. useTheme())" | "Theme-dependent template literals require a project-specific theme source (e.g. useTheme())" | "Theme prop overrides on styled components are not supported" | "Universal selectors (`*`) are currently unsupported" | "Unsupported call expression (expected imported helper(...) or imported helper(...)(...))" | "Unsupported conditional test in shouldForwardProp" | "Unsupported .attrs() callback pattern" | "Unsupported shouldForwardProp pattern (only !prop.startsWith(), ![].includes(prop), and prop !== are supported)" | "Unsupported interpolation: arrow function" | "Unsupported interpolation: call expression" | "Unsupported interpolation: identifier" | "Unsupported interpolation: member expression" | "Unsupported interpolation: property" | "Unsupported interpolation: unknown" | "Unsupported nested conditional interpolation" | "Unsupported prop-based inline style expression cannot be safely inlined" | "Unsupported prop-based inline style props.theme access is not supported" | "Unsupported selector interpolation: imported value in selector position" | "Unsupported: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Unsupported selector: class selector" | "Unsupported selector: comma-separated selectors must all be simple pseudos or pseudo-elements" | "Unsupported selector: descendant pseudo selector (space before pseudo)" | "Unsupported selector: adjacent sibling combinator" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: conditional css block inside pseudo-element selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: pseudo-class on pseudo-element selector" | "Unsupported selector: unsupported pseudo-element" | "Unsupported selector: sibling combinator" | "Unsupported selector: unresolved interpolation in sibling selector" | "Unsupported selector: ambiguous element selector" | "Unsupported selector: attribute selector on unsupported element" | "Unsupported selector: element selector on exported component" | "Unsupported selector: element selector with combined ancestor and child pseudos" | "Unsupported selector: element selector with dynamic children" | "Unsupported selector: element selector with plain intrinsic children" | "Unsupported selector: element selector pseudo collision" | "Unsupported selector: cross-file component selector target has no JSX usage in this file" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in attribute selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: unresolved interpolation in cross-component sibling selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: computed media query inside ancestor attribute selector" | "Unsupported selector: computed media query inside cross-component sibling selector" | "Unsupported selector: computed media query inside sibling selector" | "Unsupported selector: computed media query inside :has() component selector" | "Unsupported selector: cross-file :has() component selector not yet supported" | "Unsupported selector: unresolved interpolation in :has() component selector" | "Unsupported selector: unknown component selector" | "Unsupported selector: component selector with child pseudo" | "Unsupported selector: component selector target has no patchable JSX usage under selector parent" | "Unsupported selector: compound pseudo selector" | "Unsupported css`` mixin: after-base mixin style is not a plain object" | "Unsupported css`` mixin: nested contextual conditions in after-base mixin" | "Unsupported css`` mixin: cannot infer base default for after-base contextual override (base value is non-literal)" | "css`` helper function interpolation references closure variable that cannot be hoisted" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead" | "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts" | "Partial transform would have a StyleX leaf wrap a styled-components base — the extending component was transformed but its base was not, so the leaf's StyleX overrides cannot reliably beat the base's styled-components styles" | "Transient $-prefixed props renamed on exported component — update consumer call sites to use the new prop names" | "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens" | "animation shorthand contains a var() with no classifiable fallback — its longhand position cannot be determined statically; bind the variable to a specific longhand (e.g. animation-duration: var(--x)) instead";
924
+ type WarningType = "`css` helper function switch must return css templates in all branches" | "`css` helper usage as a function call (css(...)) is not supported" | "`css` helper used outside of a styled component template cannot be statically transformed" | "Adapter helper call in border interpolation did not resolve to a single CSS value" | "Adapter resolveCall returned an unparseable styles expression" | "Adapter resolveCall returned an unparseable value expression" | "Adapter resolveCall returned StyleX styles for helper call where a CSS value was expected" | "Adapter resolved an imported helper call as StyleX styles without replacing the RuleSet helper" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolveBaseComponent threw an error" | "Adapter resolved StyleX styles cannot be applied under nested selectors/at-rules" | "Adapter resolved StyleX styles inside pseudo selector but did not provide cssText for property expansion — add cssText to resolveCall result to enable pseudo-wrapping" | 'Adapter resolveCall cssText could not be parsed as CSS declarations — expected semicolon-separated property: value pairs (e.g. "white-space: nowrap; overflow: hidden;")' | "Adapter resolveValue returned an unparseable value expression" | "Adapter resolveValue returned undefined for imported value" | "Arrow function: body is not a recognized pattern (expected ternary, logical, call, or member expression)" | "Arrow function: conditional branches could not be resolved to static or theme values" | "Arrow function: helper call body is not supported" | "Arrow function: indexed theme lookup pattern not matched" | "Arrow function: logical expression pattern not supported" | "Arrow function: prop access cannot be converted to style function for this CSS property" | "Arrow function: theme access path could not be resolved" | "Component selectors like `${OtherComponent}:hover &` are not directly representable in StyleX. Manual refactor is required" | "Conditional `css` block: !important is not supported in StyleX" | "Conditional `css` block: @-rules (e.g., @media, @supports) are not supported" | "CSS block contains unsupported at-rule (only @media and @container are supported; @supports, etc. require manual handling)" | "Conditional `css` block: dynamic interpolation could not be resolved to a single component prop" | "Conditional `css` block: failed to parse expression" | "Conditional `css` block: missing CSS property name" | "Conditional `css` block: missing interpolation expression" | "Conditional `css` block: mixed static/dynamic values with non-theme expressions cannot be safely transformed" | "Conditional `css` block: multiple interpolation slots in a single property value" | "Conditional `css` block: ternary branch value could not be resolved (imported values require adapter support)" | "Conditional `css` block: ternary expressions inside pseudo selectors are not supported" | "Conditional `css` block: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "Resolved border helper value could not be expanded to longhand properties" | "Resolved conditional border variant could not be expanded to longhand properties" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "Failed to parse theme expressions" | "Heterogeneous background values (mix of gradients and colors) not currently supported" | "Higher-order styled factory wrappers (e.g. hoc(styled)) are not supported" | "Imported CSS helper mixins: cannot determine inherited properties for correct pseudo selector handling" | "Local helper function returns CSS that cannot be decomposed into individual properties" | "Local helper function computes CSS values that cannot be statically traced to the component prop" | "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand" | "Styled-components specificity hacks like `&&` / `&&&` are not representable in StyleX" | "Theme-dependent block-level conditional could not be fully resolved (branches may contain dynamic interpolations)" | "Theme-dependant call expression could not be resolved (e.g. theme helper calls like theme.highlight() are not supported)" | "Theme value with fallback (props.theme.X ?? / || default) cannot be resolved statically — use adapter.resolveValue to map theme paths to StyleX tokens" | "Theme-dependent nested prop access requires a project-specific theme source (e.g. useTheme())" | "Theme-dependent template literals require a project-specific theme source (e.g. useTheme())" | "Theme prop overrides on styled components are not supported" | "Universal selectors (`*`) are currently unsupported" | "Unsupported call expression (expected imported helper(...) or imported helper(...)(...))" | "Unsupported conditional test in shouldForwardProp" | "Unsupported .attrs() callback pattern" | "Unsupported shouldForwardProp pattern (only !prop.startsWith(), ![].includes(prop), and prop !== are supported)" | "Unsupported interpolation: arrow function" | "Unsupported interpolation: call expression" | "Unsupported interpolation: identifier" | "Unsupported interpolation: member expression" | "Unsupported interpolation: property" | "Unsupported interpolation: unknown" | "Unsupported nested conditional interpolation" | "Unsupported prop-based inline style expression cannot be safely inlined" | "Unsupported prop-based inline style props.theme access is not supported" | "Unsupported selector interpolation: imported value in selector position" | "Unsupported: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Unsupported selector: class selector" | "Unsupported selector: comma-separated selectors must all be simple pseudos or pseudo-elements" | "Unsupported selector: descendant pseudo selector (space before pseudo)" | "Unsupported selector: adjacent sibling combinator" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: conditional css block inside pseudo-element selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: pseudo-class on pseudo-element selector" | "Unsupported selector: unsupported pseudo-element" | "Unsupported selector: sibling combinator" | "Unsupported selector: unresolved interpolation in sibling selector" | "Unsupported selector: ambiguous element selector" | "Unsupported selector: attribute selector on unsupported element" | "Unsupported selector: element selector on exported component" | "Unsupported selector: element selector with combined ancestor and child pseudos" | "Unsupported selector: element selector with dynamic children" | "Unsupported selector: element selector with plain intrinsic children" | "Unsupported selector: element selector pseudo collision" | "Unsupported selector: cross-file component selector target has no JSX usage in this file" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in attribute selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: unresolved interpolation in cross-component sibling selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: computed media query inside ancestor attribute selector" | "Unsupported selector: computed media query inside cross-component sibling selector" | "Unsupported selector: computed media query inside sibling selector" | "Unsupported selector: computed media query inside :has() component selector" | "Unsupported selector: cross-file :has() component selector not yet supported" | "Unsupported selector: unresolved interpolation in :has() component selector" | "Unsupported selector: unknown component selector" | "Unsupported selector: component selector with child pseudo" | "Unsupported selector: component selector target has no patchable JSX usage under selector parent" | "Unsupported selector: compound pseudo selector" | "Unsupported css`` mixin: after-base mixin style is not a plain object" | "Unsupported css`` mixin: nested contextual conditions in after-base mixin" | "Unsupported css`` mixin: cannot infer base default for after-base contextual override (base value is non-literal)" | "css`` helper function interpolation references closure variable that cannot be hoisted" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead" | "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts" | "Partial transform would have a StyleX leaf wrap a styled-components base — the extending component was transformed but its base was not, so the leaf's StyleX overrides cannot reliably beat the base's styled-components styles" | "Transient $-prefixed props renamed on exported component — update consumer call sites to use the new prop names" | "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens" | "animation shorthand contains a var() with no classifiable fallback — its longhand position cannot be determined statically; bind the variable to a specific longhand (e.g. animation-duration: var(--x)) instead";
925
925
  interface WarningLog {
926
926
  severity: Severity;
927
927
  type: WarningType;
@@ -1,4 +1,4 @@
1
- import { i as TransformResult, r as TransformOptions, t as BridgeComponentResult } from "./transform-types-DUT5eSAm.mjs";
1
+ import { i as TransformResult, r as TransformOptions, t as BridgeComponentResult } from "./transform-types-Bl-oPkjl.mjs";
2
2
  import { API, FileInfo, Options } from "jscodeshift";
3
3
 
4
4
  //#region src/transform.d.ts