styled-components-to-stylex-codemod 0.0.49 → 0.0.51

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,10 +1,12 @@
1
1
  import path from "node:path";
2
2
  import { readFileSync } from "node:fs";
3
+ import { parse } from "@babel/parser";
3
4
  //#region src/internal/logger.ts
4
5
  /**
5
6
  * Logger and warning types for transform diagnostics.
6
7
  * Core concepts: severity classification and source context reporting.
7
8
  */
9
+ const CASCADE_CONFLICT_WARNING = "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts";
8
10
  const UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING = "Unsupported shouldForwardProp pattern (only !prop.startsWith(), ![].includes(prop), and prop !== are supported)";
9
11
  /**
10
12
  * When fileCount <= this threshold, warnings are printed per-file inline and
@@ -134,6 +136,7 @@ function createContextReplacer() {
134
136
  return value;
135
137
  };
136
138
  }
139
+ const MAX_DEPENDED_FILE_GROUPS = 15;
137
140
  var LoggerReport = class {
138
141
  warnings;
139
142
  fileCount;
@@ -163,6 +166,20 @@ var LoggerReport = class {
163
166
  lines.push("");
164
167
  lines.push(`▸ ${group.message} (${group.warnings.length})`);
165
168
  lines.push("");
169
+ const dependedFileGroups = this.groupDependedFiles(group);
170
+ if (dependedFileGroups.length > 0) {
171
+ lines.push(" Top depended files:");
172
+ lines.push("");
173
+ for (const [index, dependedFileGroup] of dependedFileGroups.entries()) {
174
+ const usageCount = dependedFileGroup.usageFiles.length;
175
+ const usageLabel = usageCount === 1 ? "usage file" : "usage files";
176
+ lines.push(` ${index + 1}. ${dependedFileGroup.dependedFilePath} (${usageCount} ${usageLabel})`);
177
+ for (const usageFile of dependedFileGroup.usageFiles.slice(0, MAX_EXAMPLES)) lines.push(` ${usageFile}`);
178
+ const remainingUsageFiles = usageCount - MAX_EXAMPLES;
179
+ if (remainingUsageFiles > 0) lines.push(` ... and ${remainingUsageFiles} more usage file(s)`);
180
+ lines.push("");
181
+ }
182
+ }
166
183
  const seenFiles = /* @__PURE__ */ new Set();
167
184
  const uniqueLocations = [];
168
185
  for (const loc of group.warnings) if (!seenFiles.has(loc.filePath)) {
@@ -212,6 +229,21 @@ var LoggerReport = class {
212
229
  }
213
230
  return Array.from(groupMap.values()).sort((a, b) => b.warnings.length - a.warnings.length);
214
231
  }
232
+ groupDependedFiles(group) {
233
+ if (group.message !== "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts") return [];
234
+ const groupMap = /* @__PURE__ */ new Map();
235
+ for (const warning of group.warnings) {
236
+ const dependedFilePath = getCascadeDependedFilePath(warning);
237
+ if (!dependedFilePath) continue;
238
+ const dependedFileWarnings = groupMap.get(dependedFilePath) ?? [];
239
+ dependedFileWarnings.push(warning);
240
+ groupMap.set(dependedFilePath, dependedFileWarnings);
241
+ }
242
+ return Array.from(groupMap.entries()).map(([dependedFilePath, warnings]) => ({
243
+ dependedFilePath,
244
+ usageFiles: uniqueSorted(warnings.map((warning) => warning.filePath))
245
+ })).sort((a, b) => b.usageFiles.length - a.usageFiles.length).slice(0, MAX_DEPENDED_FILE_GROUPS);
246
+ }
215
247
  getSnippet(filePath, loc) {
216
248
  if (!loc) return;
217
249
  const lines = this.getFileLines(filePath);
@@ -240,6 +272,18 @@ var LoggerReport = class {
240
272
  }
241
273
  }
242
274
  };
275
+ function getCascadeDependedFilePath(warning) {
276
+ const context = warning.context;
277
+ if (!context || typeof context !== "object") return;
278
+ const record = context;
279
+ const definitionPath = record.definitionPath;
280
+ if (typeof definitionPath === "string") return definitionPath;
281
+ const importedPath = record.importedPath;
282
+ return typeof importedPath === "string" ? importedPath : void 0;
283
+ }
284
+ function uniqueSorted(values) {
285
+ return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
286
+ }
243
287
  const WARN_BG_COLOR = "\x1B[43m";
244
288
  const WARN_TEXT_COLOR = "\x1B[30m";
245
289
  const ERROR_BG_COLOR = "\x1B[41m";
@@ -380,6 +424,103 @@ function getFileImportsFromRes(name) {
380
424
  return cached;
381
425
  }
382
426
  //#endregion
427
+ //#region src/internal/prepass/prepass-parser.ts
428
+ /**
429
+ * Shared babel parser for prepass modules.
430
+ *
431
+ * Uses @babel/parser directly with `tokens: false` for ~35% faster parsing
432
+ * compared to jscodeshift's getParser (which enables token generation).
433
+ *
434
+ * Both scan-cross-file-selectors and extract-external-interface can share this parser
435
+ * to avoid duplicate parser initialization.
436
+ */
437
+ /**
438
+ * Create a babel parser with tokens disabled, matching jscodeshift's plugin set
439
+ * for the given parser name.
440
+ *
441
+ * - `tsx` / `ts`: TypeScript plugins (tsx also includes JSX)
442
+ * - `babel` / `babylon` / `flow`: Flow plugins + JSX
443
+ *
444
+ * Note: jscodeshift's `flow` parser uses the `flow-parser` package (not babel).
445
+ * We always use `@babel/parser` with the `flow` plugin instead, since it produces
446
+ * the same AST node types (ImportDeclaration, TaggedTemplateExpression) that the
447
+ * prepass walks, and avoids an extra parser dependency.
448
+ */
449
+ function createPrepassParser(parserName = "tsx") {
450
+ const options = parserName === "ts" || parserName === "tsx" ? buildOptions(TS_PLUGINS, parserName === "tsx") : buildOptions(FLOW_PLUGINS, true);
451
+ return { parse(source) {
452
+ return parse(source, options);
453
+ } };
454
+ }
455
+ function buildOptions(plugins, includeJsx) {
456
+ return {
457
+ sourceType: "module",
458
+ allowImportExportEverywhere: true,
459
+ allowReturnOutsideFunction: true,
460
+ startLine: 1,
461
+ tokens: false,
462
+ plugins: includeJsx ? ["jsx", ...plugins] : plugins
463
+ };
464
+ }
465
+ /**
466
+ * Plugins for TypeScript parsers (ts, tsx).
467
+ * Same as jscodeshift's tsOptions.plugins minus "jsx" (added conditionally).
468
+ */
469
+ const TS_PLUGINS = [
470
+ "asyncGenerators",
471
+ "decoratorAutoAccessors",
472
+ "bigInt",
473
+ "classPrivateMethods",
474
+ "classPrivateProperties",
475
+ "classProperties",
476
+ "decorators-legacy",
477
+ "doExpressions",
478
+ "dynamicImport",
479
+ "exportDefaultFrom",
480
+ "exportNamespaceFrom",
481
+ "functionBind",
482
+ "functionSent",
483
+ "importAttributes",
484
+ "importMeta",
485
+ "nullishCoalescingOperator",
486
+ "numericSeparator",
487
+ "objectRestSpread",
488
+ "optionalCatchBinding",
489
+ "optionalChaining",
490
+ ["pipelineOperator", { proposal: "minimal" }],
491
+ "throwExpressions",
492
+ "typescript"
493
+ ];
494
+ /**
495
+ * Plugins for Flow/Babylon parsers (babel, babylon, flow).
496
+ * Same as jscodeshift's babylon parser plugins minus "jsx" (added conditionally).
497
+ */
498
+ const FLOW_PLUGINS = [
499
+ ["flow", { all: true }],
500
+ "flowComments",
501
+ "asyncGenerators",
502
+ "bigInt",
503
+ "classProperties",
504
+ "classPrivateProperties",
505
+ "classPrivateMethods",
506
+ ["decorators", { decoratorsBeforeExport: false }],
507
+ "doExpressions",
508
+ "dynamicImport",
509
+ "exportDefaultFrom",
510
+ "exportNamespaceFrom",
511
+ "functionBind",
512
+ "functionSent",
513
+ "importMeta",
514
+ "logicalAssignment",
515
+ "nullishCoalescingOperator",
516
+ "numericSeparator",
517
+ "objectRestSpread",
518
+ "optionalCatchBinding",
519
+ "optionalChaining",
520
+ ["pipelineOperator", { proposal: "minimal" }],
521
+ "throwExpressions"
522
+ ];
523
+ //#endregion
383
524
  //#region src/internal/utilities/ast-walk.ts
384
525
  const SKIPPED_KEYS = new Set([
385
526
  "loc",
@@ -405,4 +546,4 @@ function walkAst(root, visitor) {
405
546
  visit(root);
406
547
  }
407
548
  //#endregion
408
- export { getReExportedSourceName as a, Logger as c, findImportSource as i, UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING as l, fileExports as n, resolveBarrelReExport as o, fileImportsFrom as r, resolveBarrelReExportBinding as s, walkAst as t };
549
+ export { findImportSource as a, resolveBarrelReExportBinding as c, UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING as d, fileImportsFrom as i, CASCADE_CONFLICT_WARNING as l, createPrepassParser as n, getReExportedSourceName as o, fileExports as r, resolveBarrelReExport as s, walkAst as t, Logger as u };
@@ -1,5 +1,5 @@
1
1
  import { r as toRealPath } from "./path-utils-BC4U8X_q.mjs";
2
- import { r as escapeRegex } from "./string-utils-DD9wdRHW.mjs";
2
+ import { r as escapeRegex } from "./string-utils-BYTEHwNg.mjs";
3
3
  import { t as isSelectorContext } from "./selector-context-heuristic-LVizWWOR.mjs";
4
4
  import { readFileSync } from "node:fs";
5
5
  //#region src/internal/bridge-consumer-patcher.ts
@@ -1,5 +1,4 @@
1
- import { i as findImportSource, s as resolveBarrelReExportBinding } from "./ast-walk-DigTJqU7.mjs";
2
- import { parse } from "@babel/parser";
1
+ import { a as findImportSource, c as resolveBarrelReExportBinding } from "./ast-walk-BOXS-DT7.mjs";
3
2
  //#region src/internal/prepass/compute-leaf-set.ts
4
3
  /**
5
4
  * Computes which styled-component bindings are "leaves" for leaves-only mode:
@@ -240,101 +239,4 @@ function findDefaultExportedLocalName(source) {
240
239
  return source.match(/\bexport\s+default\s+([A-Z][A-Za-z0-9]*)\b/)?.[1] ?? source.match(/\bexport\s*\{[^}]*\b([A-Z][A-Za-z0-9]*)\s+as\s+default\b[^}]*\}/)?.[1];
241
240
  }
242
241
  //#endregion
243
- //#region src/internal/prepass/prepass-parser.ts
244
- /**
245
- * Shared babel parser for prepass modules.
246
- *
247
- * Uses @babel/parser directly with `tokens: false` for ~35% faster parsing
248
- * compared to jscodeshift's getParser (which enables token generation).
249
- *
250
- * Both scan-cross-file-selectors and extract-external-interface can share this parser
251
- * to avoid duplicate parser initialization.
252
- */
253
- /**
254
- * Create a babel parser with tokens disabled, matching jscodeshift's plugin set
255
- * for the given parser name.
256
- *
257
- * - `tsx` / `ts`: TypeScript plugins (tsx also includes JSX)
258
- * - `babel` / `babylon` / `flow`: Flow plugins + JSX
259
- *
260
- * Note: jscodeshift's `flow` parser uses the `flow-parser` package (not babel).
261
- * We always use `@babel/parser` with the `flow` plugin instead, since it produces
262
- * the same AST node types (ImportDeclaration, TaggedTemplateExpression) that the
263
- * prepass walks, and avoids an extra parser dependency.
264
- */
265
- function createPrepassParser(parserName = "tsx") {
266
- const options = parserName === "ts" || parserName === "tsx" ? buildOptions(TS_PLUGINS, parserName === "tsx") : buildOptions(FLOW_PLUGINS, true);
267
- return { parse(source) {
268
- return parse(source, options);
269
- } };
270
- }
271
- function buildOptions(plugins, includeJsx) {
272
- return {
273
- sourceType: "module",
274
- allowImportExportEverywhere: true,
275
- allowReturnOutsideFunction: true,
276
- startLine: 1,
277
- tokens: false,
278
- plugins: includeJsx ? ["jsx", ...plugins] : plugins
279
- };
280
- }
281
- /**
282
- * Plugins for TypeScript parsers (ts, tsx).
283
- * Same as jscodeshift's tsOptions.plugins minus "jsx" (added conditionally).
284
- */
285
- const TS_PLUGINS = [
286
- "asyncGenerators",
287
- "decoratorAutoAccessors",
288
- "bigInt",
289
- "classPrivateMethods",
290
- "classPrivateProperties",
291
- "classProperties",
292
- "decorators-legacy",
293
- "doExpressions",
294
- "dynamicImport",
295
- "exportDefaultFrom",
296
- "exportNamespaceFrom",
297
- "functionBind",
298
- "functionSent",
299
- "importAttributes",
300
- "importMeta",
301
- "nullishCoalescingOperator",
302
- "numericSeparator",
303
- "objectRestSpread",
304
- "optionalCatchBinding",
305
- "optionalChaining",
306
- ["pipelineOperator", { proposal: "minimal" }],
307
- "throwExpressions",
308
- "typescript"
309
- ];
310
- /**
311
- * Plugins for Flow/Babylon parsers (babel, babylon, flow).
312
- * Same as jscodeshift's babylon parser plugins minus "jsx" (added conditionally).
313
- */
314
- const FLOW_PLUGINS = [
315
- ["flow", { all: true }],
316
- "flowComments",
317
- "asyncGenerators",
318
- "bigInt",
319
- "classProperties",
320
- "classPrivateProperties",
321
- "classPrivateMethods",
322
- ["decorators", { decoratorsBeforeExport: false }],
323
- "doExpressions",
324
- "dynamicImport",
325
- "exportDefaultFrom",
326
- "exportNamespaceFrom",
327
- "functionBind",
328
- "functionSent",
329
- "importMeta",
330
- "logicalAssignment",
331
- "nullishCoalescingOperator",
332
- "numericSeparator",
333
- "objectRestSpread",
334
- "optionalCatchBinding",
335
- "optionalChaining",
336
- ["pipelineOperator", { proposal: "minimal" }],
337
- "throwExpressions"
338
- ];
339
- //#endregion
340
- export { extractStyledDefBasesFromSource as i, computeGlobalLeafKeys as n, extractStyledDefBasesFromAstProgram as r, createPrepassParser as t };
242
+ export { extractStyledDefBasesFromAstProgram as n, extractStyledDefBasesFromSource as r, computeGlobalLeafKeys as t };
@@ -1,5 +1,5 @@
1
1
  import { r as toRealPath } from "./path-utils-BC4U8X_q.mjs";
2
- import { r as escapeRegex } from "./string-utils-DD9wdRHW.mjs";
2
+ import { r as escapeRegex } from "./string-utils-BYTEHwNg.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  //#region src/internal/forwarded-as-consumer-patcher.ts
5
5
  /**
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-CHRHLCj_.mjs";
1
+ import { a as CollectedWarning, c as MarkerFileContext, l as defineAdapter, n as TransformMode, o as AdapterInput, s as ImportSource } from "./transform-types-BIv4-1OO.mjs";
2
2
 
3
3
  //#region src/run.d.ts
4
4
  interface RunTransformOptions {
@@ -127,6 +127,12 @@ interface RunTransformResult {
127
127
  * import { defineAdapter } from 'styled-components-to-stylex-codemod';
128
128
  *
129
129
  * const adapter = defineAdapter({
130
+ * styleMerger: null,
131
+ * useSxProp: false,
132
+ * usePhysicalProperties: true,
133
+ * externalInterface() {
134
+ * return { styles: false, as: false, ref: false };
135
+ * },
130
136
  * resolveValue(ctx) {
131
137
  * if (ctx.kind !== "theme") return null;
132
138
  * return {
@@ -134,6 +140,12 @@ interface RunTransformResult {
134
140
  * imports: [{ from: { kind: "specifier", value: "./theme.stylex" }, names: [{ imported: "themeVars" }] }],
135
141
  * };
136
142
  * },
143
+ * resolveCall() {
144
+ * return null;
145
+ * },
146
+ * resolveSelector() {
147
+ * return undefined;
148
+ * },
137
149
  * });
138
150
  *
139
151
  * await runTransform({
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { c as describeValue, i as defineAdapter, n as mergeMarkerDeclarations, s as assertValidAdapterInput, t as transformedComponentAcceptsSx } from "./sx-surface-BzqO3hcC.mjs";
2
- import { c as Logger, o as resolveBarrelReExport, t as walkAst } from "./ast-walk-DigTJqU7.mjs";
3
- import { i as extractStyledDefBasesFromSource, t as createPrepassParser } from "./prepass-parser-CwdDzSgx.mjs";
1
+ import { c as describeValue, i as defineAdapter, n as mergeMarkerDeclarations, s as assertValidAdapterInput, t as transformedComponentAcceptsSx } from "./sx-surface-CEPFSTO1.mjs";
2
+ import { n as createPrepassParser, s as resolveBarrelReExport, t as walkAst, u as Logger } from "./ast-walk-BOXS-DT7.mjs";
3
+ import { r as extractStyledDefBasesFromSource } from "./compute-leaf-set-ghdXvfbp.mjs";
4
4
  import { r as toRealPath } from "./path-utils-BC4U8X_q.mjs";
5
5
  import jscodeshift from "jscodeshift";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -179,6 +179,12 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
179
179
  * import { defineAdapter } from 'styled-components-to-stylex-codemod';
180
180
  *
181
181
  * const adapter = defineAdapter({
182
+ * styleMerger: null,
183
+ * useSxProp: false,
184
+ * usePhysicalProperties: true,
185
+ * externalInterface() {
186
+ * return { styles: false, as: false, ref: false };
187
+ * },
182
188
  * resolveValue(ctx) {
183
189
  * if (ctx.kind !== "theme") return null;
184
190
  * return {
@@ -186,6 +192,12 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
186
192
  * imports: [{ from: { kind: "specifier", value: "./theme.stylex" }, names: [{ imported: "themeVars" }] }],
187
193
  * };
188
194
  * },
195
+ * resolveCall() {
196
+ * return null;
197
+ * },
198
+ * resolveSelector() {
199
+ * return undefined;
200
+ * },
189
201
  * });
190
202
  *
191
203
  * await runTransform({
@@ -204,7 +216,15 @@ async function runTransform(options) {
204
216
  "",
205
217
  "Example (plain JS):",
206
218
  " import { runTransform, defineAdapter } from \"styled-components-to-stylex-codemod\";",
207
- " const adapter = defineAdapter({ resolveValue() { return null; } });",
219
+ " const adapter = defineAdapter({",
220
+ " styleMerger: null,",
221
+ " useSxProp: false,",
222
+ " usePhysicalProperties: true,",
223
+ " externalInterface() { return { styles: false, as: false, ref: false }; },",
224
+ " resolveValue() { return null; },",
225
+ " resolveCall() { return null; },",
226
+ " resolveSelector() { return undefined; },",
227
+ " });",
208
228
  " await runTransform({ files: \"src/**/*.tsx\", consumerPaths: null, adapter });"
209
229
  ].join("\n"));
210
230
  const filesValue = options.files;
@@ -305,7 +325,7 @@ async function runTransform(options) {
305
325
  const { createModuleResolver } = await import("./resolve-imports-DgSAddIF.mjs").then((n) => n.n);
306
326
  const sharedResolver = createModuleResolver();
307
327
  filePaths = orderFilesByLocalImportDependencies(filePaths, sharedResolver, toRealPath);
308
- const { runPrepass } = await import("./run-prepass-BWQCThfh.mjs");
328
+ const { runPrepass } = await import("./run-prepass-CWnoXqI6.mjs");
309
329
  const absoluteFiles = filePaths.map((f) => resolve(f));
310
330
  const absoluteConsumers = consumerFilePaths.map((f) => resolve(f));
311
331
  let prepassResult;
@@ -332,6 +352,7 @@ async function runTransform(options) {
332
352
  componentsNeedingMarkerSidecar: /* @__PURE__ */ new Map(),
333
353
  componentsNeedingGlobalSelectorBridge: /* @__PURE__ */ new Map(),
334
354
  propUsageByFile: /* @__PURE__ */ new Map(),
355
+ stylexComponentFiles: /* @__PURE__ */ new Map(),
335
356
  globalLeafKeys: leavesOnly ? /* @__PURE__ */ new Set() : void 0
336
357
  },
337
358
  consumerAnalysis: void 0,
@@ -340,10 +361,12 @@ async function runTransform(options) {
340
361
  };
341
362
  }
342
363
  const transformedFiles = /* @__PURE__ */ new Set();
364
+ const transformedComponents = /* @__PURE__ */ new Map();
343
365
  const transformedFileSources = /* @__PURE__ */ new Map();
344
366
  const crossFilePrepassResult = {
345
367
  ...prepassResult.crossFileInfo,
346
368
  transformedFiles,
369
+ transformedComponents,
347
370
  typeScriptMetadata: prepassResult.typeScriptMetadata
348
371
  };
349
372
  const resolvedAdapter = (() => {
@@ -472,6 +495,7 @@ async function runTransform(options) {
472
495
  sidecarFiles,
473
496
  bridgeResults,
474
497
  transformedFiles,
498
+ transformedComponents,
475
499
  transformedFileSources,
476
500
  transientPropRenames,
477
501
  allowPartialMigration: options.allowPartialMigration ?? (leavesOnly ? true : false),
@@ -491,14 +515,34 @@ async function runTransform(options) {
491
515
  sidecarFiles: /* @__PURE__ */ new Map(),
492
516
  bridgeResults: /* @__PURE__ */ new Map(),
493
517
  transformedFiles: /* @__PURE__ */ new Set(),
518
+ transformedComponents: /* @__PURE__ */ new Map(),
494
519
  transformedFileSources: /* @__PURE__ */ new Map(),
495
520
  transientPropRenames: /* @__PURE__ */ new Map(),
496
521
  crossFilePrepassResult: {
497
522
  ...crossFilePrepassResult,
498
- transformedFiles: /* @__PURE__ */ new Set()
523
+ transformedFiles: /* @__PURE__ */ new Set(),
524
+ transformedComponents: /* @__PURE__ */ new Map()
499
525
  },
500
526
  silent: true,
501
- isolateFiles: true
527
+ isolateFiles: true,
528
+ createIsolatedOptions(filePath) {
529
+ const isolatedTransformedFiles = /* @__PURE__ */ new Set();
530
+ const isolatedTransformedComponents = /* @__PURE__ */ new Map();
531
+ return {
532
+ ...runnerOptions,
533
+ dry: true,
534
+ print: false,
535
+ sidecarFiles: /* @__PURE__ */ new Map(),
536
+ bridgeResults: /* @__PURE__ */ new Map(),
537
+ transformedFiles: isolatedTransformedFiles,
538
+ transformedComponents: isolatedTransformedComponents,
539
+ transformedFileSources: /* @__PURE__ */ new Map(),
540
+ transientPropRenames: /* @__PURE__ */ new Map(),
541
+ crossFilePrepassResult: createStandalonePrepassResult(crossFilePrepassResult, filePath, isolatedTransformedFiles, isolatedTransformedComponents),
542
+ silent: true,
543
+ isolateFiles: true
544
+ };
545
+ }
502
546
  });
503
547
  standaloneWarnings = Logger.createReport().getWarnings();
504
548
  Logger._clearCollected();
@@ -507,7 +551,7 @@ async function runTransform(options) {
507
551
  const result = await runTransformSequentially(transformModule, filePaths, runnerOptions);
508
552
  if (sidecarFiles.size > 0 && !dryRun) for (const [sidecarPath, content] of sidecarFiles) await writeFile(sidecarPath, mergeSidecarContent(sidecarPath, content), "utf-8");
509
553
  if (bridgeResults.size > 0 && !dryRun) {
510
- const { buildConsumerReplacements, patchConsumerFile } = await import("./bridge-consumer-patcher-CjR2kIOd.mjs");
554
+ const { buildConsumerReplacements, patchConsumerFile } = await import("./bridge-consumer-patcher-BlOkZiEv.mjs");
511
555
  const consumerReplacements = buildConsumerReplacements(crossFilePrepassResult.selectorUsages, bridgeResults, transformedFiles);
512
556
  const patchedFiles = [];
513
557
  for (const [consumerPath, replacements] of consumerReplacements) {
@@ -520,7 +564,7 @@ async function runTransform(options) {
520
564
  if (formatterCommands && patchedFiles.length > 0) await runFormatters(formatterCommands, patchedFiles);
521
565
  }
522
566
  if (prepassResult.forwardedAsConsumers.size > 0 && !dryRun) {
523
- const { buildForwardedAsReplacements, patchConsumerForwardedAs } = await import("./forwarded-as-consumer-patcher-CaLmjoiP.mjs");
567
+ const { buildForwardedAsReplacements, patchConsumerForwardedAs } = await import("./forwarded-as-consumer-patcher-CPBlZAjY.mjs");
524
568
  const forwardedAsReplacements = buildForwardedAsReplacements(prepassResult.forwardedAsConsumers, transformedFiles);
525
569
  const patchedFiles = [];
526
570
  for (const [consumerPath, entries] of forwardedAsReplacements) {
@@ -533,7 +577,7 @@ async function runTransform(options) {
533
577
  if (formatterCommands && patchedFiles.length > 0) await runFormatters(formatterCommands, patchedFiles);
534
578
  }
535
579
  if (transientPropRenames.size > 0 && !dryRun) {
536
- const { collectTransientPropPatches } = await import("./transient-prop-consumer-patcher-DGSFnxSo.mjs");
580
+ const { collectTransientPropPatches } = await import("./transient-prop-consumer-patcher-DpfimNca.mjs");
537
581
  const patches = collectTransientPropPatches({
538
582
  transientPropRenames,
539
583
  consumerFilePaths: consumerFilePaths.map((p) => resolve(p)),
@@ -639,6 +683,47 @@ function readFileForOrdering(filePath) {
639
683
  return "";
640
684
  }
641
685
  }
686
+ function createStandalonePrepassResult(prepass, filePath, transformedFiles, transformedComponents) {
687
+ const standaloneFile = toRealPath(resolve(filePath));
688
+ const selectorUsages = /* @__PURE__ */ new Map();
689
+ const componentsNeedingMarkerSidecar = /* @__PURE__ */ new Map();
690
+ const componentsNeedingGlobalSelectorBridge = /* @__PURE__ */ new Map();
691
+ for (const [consumerPath, usages] of prepass.selectorUsages) {
692
+ const consumerIsTransformed = toRealPath(consumerPath) === standaloneFile;
693
+ const isolatedUsages = usages.map((usage) => ({
694
+ ...usage,
695
+ consumerIsTransformed
696
+ }));
697
+ selectorUsages.set(consumerPath, isolatedUsages);
698
+ for (const usage of isolatedUsages) {
699
+ if (usage.bridgeComponentName) continue;
700
+ if (consumerIsTransformed) addSetMapEntry(componentsNeedingMarkerSidecar, usage.resolvedPath, usage.importedName);
701
+ addSetMapEntry(componentsNeedingGlobalSelectorBridge, usage.resolvedPath, usage.importedName);
702
+ }
703
+ }
704
+ return {
705
+ ...prepass,
706
+ selectorUsages,
707
+ componentsNeedingMarkerSidecar,
708
+ componentsNeedingGlobalSelectorBridge,
709
+ globalLeafKeys: getStandaloneGlobalLeafKeys(prepass.globalLeafKeys, standaloneFile),
710
+ transformedFiles,
711
+ transformedComponents
712
+ };
713
+ }
714
+ function getStandaloneGlobalLeafKeys(globalLeafKeys, standaloneFile) {
715
+ if (!globalLeafKeys) return;
716
+ const filePrefix = `${standaloneFile}:`;
717
+ return new Set([...globalLeafKeys].filter((key) => key.startsWith(filePrefix)));
718
+ }
719
+ function addSetMapEntry(map, key, value) {
720
+ const values = map.get(key);
721
+ if (values) {
722
+ values.add(value);
723
+ return;
724
+ }
725
+ map.set(key, new Set([value]));
726
+ }
642
727
  async function runTransformSequentially(transformModule, filePaths, options) {
643
728
  const transform = await loadTransformFunction(transformModule);
644
729
  const aggregate = {
@@ -650,20 +735,27 @@ async function runTransformSequentially(transformModule, filePaths, options) {
650
735
  files: []
651
736
  };
652
737
  const startedAt = performance.now();
653
- const j = jscodeshift.withParser(options.parser);
654
- const api = {
655
- j,
656
- jscodeshift: j,
657
- stats: () => {},
658
- report: (msg) => {
659
- if (!options.silent) process.stdout.write(`${msg}\n`);
660
- }
738
+ const createApi = () => {
739
+ const j = jscodeshift.withParser(options.parser);
740
+ return {
741
+ j,
742
+ jscodeshift: j,
743
+ stats: () => {},
744
+ report: (msg) => {
745
+ if (!options.silent) process.stdout.write(`${msg}\n`);
746
+ }
747
+ };
661
748
  };
749
+ const sharedApi = createApi();
662
750
  for (const filePath of filePaths) {
751
+ const fileOptions = options.createIsolatedOptions?.(filePath) ?? options;
752
+ const api = fileOptions.isolateFiles === true ? createApi() : sharedApi;
663
753
  if (options.isolateFiles === true) {
664
- options.transformedFiles.clear();
665
- options.transformedFileSources.clear();
666
- options.crossFilePrepassResult?.transformedFiles?.clear();
754
+ fileOptions.transformedFiles.clear();
755
+ fileOptions.transformedComponents.clear();
756
+ fileOptions.transformedFileSources.clear();
757
+ fileOptions.crossFilePrepassResult?.transformedFiles?.clear();
758
+ fileOptions.crossFilePrepassResult?.transformedComponents?.clear();
667
759
  }
668
760
  let source;
669
761
  try {
@@ -681,8 +773,8 @@ async function runTransformSequentially(transformModule, filePaths, options) {
681
773
  const output = await transform({
682
774
  path: filePath,
683
775
  source
684
- }, api, options);
685
- if (output !== null) options.transformedFileSources.set(toRealPath(filePath), output);
776
+ }, api, fileOptions);
777
+ if (output !== null) fileOptions.transformedFileSources.set(toRealPath(filePath), output);
686
778
  if (output === null) {
687
779
  aggregate.skip += 1;
688
780
  aggregate.files.push({
@@ -699,8 +791,8 @@ async function runTransformSequentially(transformModule, filePaths, options) {
699
791
  });
700
792
  continue;
701
793
  }
702
- if (options.print) process.stdout.write(`${output}\n`);
703
- if (!options.dry) await writeFile(filePath, output, "utf-8");
794
+ if (fileOptions.print) process.stdout.write(`${output}\n`);
795
+ if (!fileOptions.dry) await writeFile(filePath, output, "utf-8");
704
796
  aggregate.ok += 1;
705
797
  aggregate.files.push({
706
798
  filePath,