styled-components-to-stylex-codemod 0.0.37 → 0.0.39
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/{bridge-consumer-patcher-CKOMofN8.mjs → bridge-consumer-patcher-31jI1854.mjs} +148 -3
- package/dist/compute-leaf-set-Drcu2eju.mjs +239 -0
- package/dist/{extract-external-interface-BgvS5GC0.mjs → extract-external-interface-CdHbvfxu.mjs} +12 -1
- package/dist/{forwarded-as-consumer-patcher-CqxniQIc.mjs → forwarded-as-consumer-patcher-BYCrqzRm.mjs} +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +44 -10
- package/dist/{merge-markers-CJ02ZuW0.mjs → merge-markers-BC5YNB7D.mjs} +85 -8
- package/dist/prop-usage-D6ZiDfzz.mjs +136 -0
- package/dist/{run-prepass-5LTAQkG0.mjs → run-prepass-qEr_Mc3y.mjs} +177 -260
- package/dist/{string-utils-ChXtospT.mjs → string-utils-DD9wdRHW.mjs} +16 -1
- package/dist/{transform-types-CY57kiqK.d.mts → transform-types-DJpFQ5xm.d.mts} +78 -7
- package/dist/transform.d.mts +1 -1
- package/dist/transform.mjs +4741 -1406
- package/dist/{transient-prop-consumer-patcher-CKAzqPfK.mjs → transient-prop-consumer-patcher-DdIYPSFk.mjs} +26 -7
- package/package.json +4 -5
- package/dist/styled-css-DVtGPEUe.mjs +0 -36
- /package/dist/{path-utils-CMR9NmMm.mjs → path-utils-BIpoL4Ue.mjs} +0 -0
- /package/dist/{selector-context-heuristic-DE3JAmpc.mjs → selector-context-heuristic-6_jSRGkZ.mjs} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as toRealPath } from "./path-utils-
|
|
2
|
-
import { r as escapeRegex } from "./string-utils-
|
|
3
|
-
import { t as isSelectorContext } from "./selector-context-heuristic-
|
|
1
|
+
import { n as toRealPath } from "./path-utils-BIpoL4Ue.mjs";
|
|
2
|
+
import { r as escapeRegex } from "./string-utils-DD9wdRHW.mjs";
|
|
3
|
+
import { t as isSelectorContext } from "./selector-context-heuristic-6_jSRGkZ.mjs";
|
|
4
4
|
import { readFileSync } from "node:fs";
|
|
5
5
|
//#region src/internal/bridge-consumer-patcher.ts
|
|
6
6
|
/**
|
|
@@ -102,6 +102,7 @@ function patchConsumerFile(filePath, replacements) {
|
|
|
102
102
|
return match;
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
+
modified = removeNowUnusedComponentImports(modified, replacements);
|
|
105
106
|
return modified !== source ? modified : null;
|
|
106
107
|
}
|
|
107
108
|
/** Find the end position of an import statement starting at startIdx (handles multi-line imports). */
|
|
@@ -119,5 +120,149 @@ function isInStyledTemplateSelectorContext(source, offset, length) {
|
|
|
119
120
|
function hasExactImportName(importSpecifiers, name) {
|
|
120
121
|
return new RegExp(`(?:^|[^A-Za-z0-9_$])${escapeRegex(name)}(?:$|[^A-Za-z0-9_$])`).test(importSpecifiers);
|
|
121
122
|
}
|
|
123
|
+
function removeNowUnusedComponentImports(source, replacements) {
|
|
124
|
+
let modified = source;
|
|
125
|
+
for (const replacement of replacements) {
|
|
126
|
+
if (hasIdentifierUsageOutsideImports(modified, replacement.localName)) continue;
|
|
127
|
+
modified = removeNamedImportSpecifier(modified, replacement.importSource, replacement.localName);
|
|
128
|
+
}
|
|
129
|
+
return modified;
|
|
130
|
+
}
|
|
131
|
+
function hasIdentifierUsageOutsideImports(source, name) {
|
|
132
|
+
const withoutImports = stripImportDeclarations(stripComments(source));
|
|
133
|
+
return new RegExp(`(^|[^A-Za-z0-9_$])${escapeRegex(name)}($|[^A-Za-z0-9_$])`).test(withoutImports);
|
|
134
|
+
}
|
|
135
|
+
function stripImportDeclarations(source) {
|
|
136
|
+
const lines = source.split(/(?<=\n)/);
|
|
137
|
+
let result = "";
|
|
138
|
+
let inImport = false;
|
|
139
|
+
let nestingDepth = 0;
|
|
140
|
+
for (const line of lines) {
|
|
141
|
+
if (!inImport && !isImportDeclarationStart(line)) {
|
|
142
|
+
result += line;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
inImport = true;
|
|
146
|
+
nestingDepth += getImportNestingDelta(line);
|
|
147
|
+
if (nestingDepth <= 0 && isImportDeclarationEnd(line)) {
|
|
148
|
+
inImport = false;
|
|
149
|
+
nestingDepth = 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
function isImportDeclarationStart(line) {
|
|
155
|
+
const match = line.match(/^[ \t]*import\b/);
|
|
156
|
+
if (!match) return false;
|
|
157
|
+
const next = line.slice(match[0].length).trimStart()[0];
|
|
158
|
+
return next !== "(" && next !== ".";
|
|
159
|
+
}
|
|
160
|
+
function isImportDeclarationEnd(line) {
|
|
161
|
+
const trimmed = line.trim();
|
|
162
|
+
return trimmed.endsWith(";") || /^import\s+["'][^"']+["']$/.test(trimmed) || /\bfrom\s+["'][^"']+["'](?:\s+with\s+\{[^}]*\})?$/.test(trimmed);
|
|
163
|
+
}
|
|
164
|
+
function getImportNestingDelta(line) {
|
|
165
|
+
let depth = 0;
|
|
166
|
+
let quote = null;
|
|
167
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
168
|
+
const char = line[index];
|
|
169
|
+
if (quote) {
|
|
170
|
+
if (char === "\\") index += 1;
|
|
171
|
+
else if (char === quote) quote = null;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (char === "'" || char === "\"") quote = char;
|
|
175
|
+
else if (char === "{" || char === "(" || char === "[") depth += 1;
|
|
176
|
+
else if (char === "}" || char === ")" || char === "]") depth -= 1;
|
|
177
|
+
}
|
|
178
|
+
return depth;
|
|
179
|
+
}
|
|
180
|
+
function stripComments(source) {
|
|
181
|
+
let result = "";
|
|
182
|
+
let state = "normal";
|
|
183
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
184
|
+
const char = source[index] ?? "";
|
|
185
|
+
const next = source[index + 1] ?? "";
|
|
186
|
+
if (state === "lineComment") {
|
|
187
|
+
if (char === "\n") {
|
|
188
|
+
result += char;
|
|
189
|
+
state = "normal";
|
|
190
|
+
} else result += " ";
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (state === "blockComment") {
|
|
194
|
+
if (char === "*" && next === "/") {
|
|
195
|
+
result += " ";
|
|
196
|
+
index += 1;
|
|
197
|
+
state = "normal";
|
|
198
|
+
} else result += char === "\n" ? "\n" : " ";
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (state === "template") {
|
|
202
|
+
if (char === "/" && next === "/") {
|
|
203
|
+
result += " ";
|
|
204
|
+
index += 1;
|
|
205
|
+
state = "lineComment";
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (char === "/" && next === "*") {
|
|
209
|
+
result += " ";
|
|
210
|
+
index += 1;
|
|
211
|
+
state = "blockComment";
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
result += char;
|
|
215
|
+
if (char === "\\") {
|
|
216
|
+
result += next;
|
|
217
|
+
index += 1;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (char === "`") state = "normal";
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (state === "singleQuote" || state === "doubleQuote") {
|
|
224
|
+
result += char;
|
|
225
|
+
if (char === "\\") {
|
|
226
|
+
result += next;
|
|
227
|
+
index += 1;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (state === "singleQuote" && char === "'" || state === "doubleQuote" && char === "\"") state = "normal";
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (char === "/" && next === "/") {
|
|
234
|
+
result += " ";
|
|
235
|
+
index += 1;
|
|
236
|
+
state = "lineComment";
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (char === "/" && next === "*") {
|
|
240
|
+
result += " ";
|
|
241
|
+
index += 1;
|
|
242
|
+
state = "blockComment";
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (char === "'") state = "singleQuote";
|
|
246
|
+
else if (char === "\"") state = "doubleQuote";
|
|
247
|
+
else if (char === "`") state = "template";
|
|
248
|
+
result += char;
|
|
249
|
+
}
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
function removeNamedImportSpecifier(source, importSource, localName) {
|
|
253
|
+
const namedImportRegex = new RegExp(`import\\s+([\\w$]+\\s*,\\s*)?\\{([^}]*)\\}\\s+from\\s+(['"]${escapeRegex(importSource)}['"]\\s*;?)`, "g");
|
|
254
|
+
return source.replace(namedImportRegex, (_match, defaultPart, specifierList, fromClause) => {
|
|
255
|
+
const remainingSpecifiers = String(specifierList).split(",").map((specifier) => specifier.trim()).filter(Boolean).filter((specifier) => getImportedSpecifierLocalName(specifier) !== localName);
|
|
256
|
+
if (remainingSpecifiers.length > 0) return `import ${defaultPart ?? ""}{ ${remainingSpecifiers.join(", ")} } from ${fromClause}`;
|
|
257
|
+
const defaultName = String(defaultPart ?? "").replace(/,\s*$/, "").trim();
|
|
258
|
+
if (defaultName) return `import ${defaultName} from ${fromClause}`;
|
|
259
|
+
return "";
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
function getImportedSpecifierLocalName(specifier) {
|
|
263
|
+
const aliasMatch = specifier.match(/\bas\s+([A-Za-z_$][\w$]*)$/);
|
|
264
|
+
if (aliasMatch?.[1]) return aliasMatch[1];
|
|
265
|
+
return specifier.trim();
|
|
266
|
+
}
|
|
122
267
|
//#endregion
|
|
123
268
|
export { buildConsumerReplacements, patchConsumerFile };
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { i as resolveBarrelReExport, r as findImportSource } from "./extract-external-interface-CdHbvfxu.mjs";
|
|
2
|
+
//#region src/internal/prepass/compute-leaf-set.ts
|
|
3
|
+
/**
|
|
4
|
+
* Computes which styled-component bindings are "leaves" for leaves-only mode:
|
|
5
|
+
* intrinsic bases (`styled.div`) or transitive wrappers around other leaf styled
|
|
6
|
+
* components in the transform set. Uses AST extraction (primary), regex fallback,
|
|
7
|
+
* fixed-point + import resolution (same helpers as consumer analysis).
|
|
8
|
+
*/
|
|
9
|
+
const RX_EXPORT_DECL = String.raw`(?:export\s+)?(?:const|let|var)\s+`;
|
|
10
|
+
/** `const Name = styled.tag` — intrinsic HTML/SVG tag member. */
|
|
11
|
+
const STYLED_INTRINSIC_MEMBER_RE = new RegExp(String.raw`\b${RX_EXPORT_DECL}([A-Z][A-Za-z0-9]*)\b[^=]*=\s*styled\.([a-z][a-zA-Z0-9]*)\b`, "g");
|
|
12
|
+
/** `const Name = styled("tag")` — intrinsic string tag. */
|
|
13
|
+
const STYLED_INTRINSIC_STRING_RE = new RegExp(String.raw`\b${RX_EXPORT_DECL}([A-Z][A-Za-z0-9]*)\b[^=]*=\s*styled\s*\(\s*["']([^"']+)["']`, "g");
|
|
14
|
+
/** `const Name = styled(Component)` — wraps another component identifier. */
|
|
15
|
+
const STYLED_COMPONENT_RE = new RegExp(String.raw`\b${RX_EXPORT_DECL}([A-Z][A-Za-z0-9]*)\b[^=]*=\s*styled\s*\(\s*([A-Z][A-Za-z0-9]*)\s*\)`, "g");
|
|
16
|
+
/**
|
|
17
|
+
* Regex-derived styled definition bases for files in the transform set.
|
|
18
|
+
* Later entries for the same component name overwrite earlier ones (rare).
|
|
19
|
+
*/
|
|
20
|
+
function extractStyledDefBasesFromSource(filePath, source, into) {
|
|
21
|
+
let map = into.get(filePath);
|
|
22
|
+
if (!map) {
|
|
23
|
+
map = /* @__PURE__ */ new Map();
|
|
24
|
+
into.set(filePath, map);
|
|
25
|
+
}
|
|
26
|
+
STYLED_INTRINSIC_MEMBER_RE.lastIndex = 0;
|
|
27
|
+
for (const m of source.matchAll(STYLED_INTRINSIC_MEMBER_RE)) {
|
|
28
|
+
const name = m[1];
|
|
29
|
+
if (name) map.set(name, { kind: "intrinsic" });
|
|
30
|
+
}
|
|
31
|
+
STYLED_INTRINSIC_STRING_RE.lastIndex = 0;
|
|
32
|
+
for (const m of source.matchAll(STYLED_INTRINSIC_STRING_RE)) {
|
|
33
|
+
const name = m[1];
|
|
34
|
+
if (name) map.set(name, { kind: "intrinsic" });
|
|
35
|
+
}
|
|
36
|
+
STYLED_COMPONENT_RE.lastIndex = 0;
|
|
37
|
+
for (const m of source.matchAll(STYLED_COMPONENT_RE)) {
|
|
38
|
+
const name = m[1];
|
|
39
|
+
const ident = m[2];
|
|
40
|
+
if (name && ident) map.set(name, {
|
|
41
|
+
kind: "component",
|
|
42
|
+
ident
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* AST-based extraction: understands `let`/`var`, export blocks, named `styled` imports,
|
|
48
|
+
* and `.attrs` / `.withConfig` chains before the tagged template.
|
|
49
|
+
* Results merge into `into`; bindings found here override regex entries for the same name.
|
|
50
|
+
*/
|
|
51
|
+
function extractStyledDefBasesFromAstProgram(filePath, program, styledLocalNames, into) {
|
|
52
|
+
if (styledLocalNames.size === 0) return;
|
|
53
|
+
let map = into.get(filePath);
|
|
54
|
+
if (!map) {
|
|
55
|
+
map = /* @__PURE__ */ new Map();
|
|
56
|
+
into.set(filePath, map);
|
|
57
|
+
}
|
|
58
|
+
const body = program.body;
|
|
59
|
+
if (!body) return;
|
|
60
|
+
for (const stmt of body) walkStatement(stmt);
|
|
61
|
+
function walkStatement(stmt) {
|
|
62
|
+
if (stmt.type === "VariableDeclaration") {
|
|
63
|
+
for (const d of stmt.declarations ?? []) processDeclarator(d);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration) walkStatement(stmt.declaration);
|
|
67
|
+
}
|
|
68
|
+
function processDeclarator(decl) {
|
|
69
|
+
if (decl.type !== "VariableDeclarator") return;
|
|
70
|
+
const id = decl.id;
|
|
71
|
+
if (id.type !== "Identifier" || typeof id.name !== "string") return;
|
|
72
|
+
const tpl = findTaggedTemplate(unwrapInitializer(decl.init));
|
|
73
|
+
if (!tpl || tpl.type !== "TaggedTemplateExpression") return;
|
|
74
|
+
const base = classifyStyledTemplateTag(tpl.tag, styledLocalNames);
|
|
75
|
+
if (base) map.set(id.name, base);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function unwrapInitializer(node) {
|
|
79
|
+
let cur = node ?? void 0;
|
|
80
|
+
while (cur) {
|
|
81
|
+
if (cur.type === "TSAsExpression" || cur.type === "AsExpression") {
|
|
82
|
+
cur = cur.expression;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (cur.type === "ParenthesizedExpression") {
|
|
86
|
+
cur = cur.expression;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
return cur;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function findTaggedTemplate(node) {
|
|
93
|
+
const n = unwrapInitializer(node);
|
|
94
|
+
if (!n) return;
|
|
95
|
+
if (n.type === "TaggedTemplateExpression") return n;
|
|
96
|
+
}
|
|
97
|
+
/** Peel `.attrs` / `.withConfig` / nested calls down to `styled.div` or `styled(X)`. */
|
|
98
|
+
function peelStyledApplication(tag, styledNames) {
|
|
99
|
+
let cur = tag;
|
|
100
|
+
while (cur) {
|
|
101
|
+
if (cur.type === "CallExpression") {
|
|
102
|
+
const callee = cur.callee;
|
|
103
|
+
if (callee?.type === "MemberExpression") {
|
|
104
|
+
cur = callee;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (callee?.type === "Identifier" && typeof callee.name === "string" && styledNames.has(callee.name)) return cur;
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
if (cur.type === "MemberExpression") {
|
|
111
|
+
const obj = cur.object;
|
|
112
|
+
if (obj?.type === "Identifier" && typeof obj.name === "string" && styledNames.has(obj.name)) return cur;
|
|
113
|
+
cur = obj;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function classifyStyledTemplateTag(tag, styledNames) {
|
|
121
|
+
const root = peelStyledApplication(tag, styledNames);
|
|
122
|
+
if (!root) return null;
|
|
123
|
+
if (root.type === "MemberExpression") {
|
|
124
|
+
const obj = root.object;
|
|
125
|
+
const prop = root.property;
|
|
126
|
+
const objName = obj?.type === "Identifier" ? obj.name : void 0;
|
|
127
|
+
if (obj?.type !== "Identifier" || typeof objName !== "string" || !styledNames.has(objName)) return null;
|
|
128
|
+
const isComputed = Boolean(root.computed);
|
|
129
|
+
if (isComputed && prop?.type === "StringLiteral" && typeof prop.value === "string") return { kind: "intrinsic" };
|
|
130
|
+
if (!isComputed && prop?.type === "Identifier" && typeof prop.name === "string") return { kind: "intrinsic" };
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
if (root.type === "CallExpression") {
|
|
134
|
+
const callee = root.callee;
|
|
135
|
+
const arg0 = root.arguments?.[0];
|
|
136
|
+
const calleeName = callee?.type === "Identifier" ? callee.name : void 0;
|
|
137
|
+
if (callee?.type !== "Identifier" || typeof calleeName !== "string" || !styledNames.has(calleeName) || !arg0) return null;
|
|
138
|
+
if (arg0.type === "Identifier" && typeof arg0.name === "string") return {
|
|
139
|
+
kind: "component",
|
|
140
|
+
ident: arg0.name
|
|
141
|
+
};
|
|
142
|
+
if (arg0.type === "StringLiteral" && typeof arg0.value === "string") return { kind: "intrinsic" };
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Fixed-point: a styled binding is a leaf if its base is intrinsic, or its base
|
|
149
|
+
* component resolves (same-file or import) to another leaf binding in the transform set.
|
|
150
|
+
*
|
|
151
|
+
* @param transformSet - Absolute realpaths of files being transformed
|
|
152
|
+
* @param styledDefBases - From {@link extractStyledDefBasesFromSource}
|
|
153
|
+
* @param resolve - Module path resolver
|
|
154
|
+
* @param cachedRead - Read file source for import resolution
|
|
155
|
+
*/
|
|
156
|
+
function computeGlobalLeafKeys(args) {
|
|
157
|
+
const { transformSet, styledDefBases, resolve, cachedRead, toRealPath, resolveBaseComponent } = args;
|
|
158
|
+
/** fileRealPath → Set of local binding names that are leaves */
|
|
159
|
+
const globalLeaves = /* @__PURE__ */ new Map();
|
|
160
|
+
const ensureSet = (file) => {
|
|
161
|
+
let s = globalLeaves.get(file);
|
|
162
|
+
if (!s) {
|
|
163
|
+
s = /* @__PURE__ */ new Set();
|
|
164
|
+
globalLeaves.set(file, s);
|
|
165
|
+
}
|
|
166
|
+
return s;
|
|
167
|
+
};
|
|
168
|
+
const isLeaf = (file, name) => globalLeaves.get(file)?.has(name) ?? false;
|
|
169
|
+
const tryResolveImportedLeaf = (file, ident) => {
|
|
170
|
+
const importInfo = findImportSource(cachedRead(file), ident);
|
|
171
|
+
if (!importInfo) return false;
|
|
172
|
+
const initialDefFile = resolve(importInfo.source, file);
|
|
173
|
+
if (!initialDefFile) return false;
|
|
174
|
+
const defReal = toRealPath(resolveBarrelReExport(initialDefFile, importInfo.isDefault ? "default" : importInfo.exportedName, resolve, cachedRead) ?? initialDefFile);
|
|
175
|
+
if (!transformSet.has(defReal)) return false;
|
|
176
|
+
return leafKeyExists(defReal, importInfo.exportedName, importInfo.isDefault, cachedRead, globalLeaves);
|
|
177
|
+
};
|
|
178
|
+
const tryResolveAdapterIntrinsic = (file, ident) => {
|
|
179
|
+
if (!resolveBaseComponent) return false;
|
|
180
|
+
const importInfo = findImportSource(cachedRead(file), ident);
|
|
181
|
+
if (!importInfo) return false;
|
|
182
|
+
try {
|
|
183
|
+
const result = resolveBaseComponent({
|
|
184
|
+
importSource: importInfo.source,
|
|
185
|
+
importedName: importInfo.exportedName,
|
|
186
|
+
staticProps: {},
|
|
187
|
+
filePath: file
|
|
188
|
+
});
|
|
189
|
+
return typeof result?.tagName === "string" && result.tagName.trim() !== "";
|
|
190
|
+
} catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
let changed = true;
|
|
195
|
+
while (changed) {
|
|
196
|
+
changed = false;
|
|
197
|
+
for (const [filePath, nameMap] of styledDefBases) {
|
|
198
|
+
const fileReal = toRealPath(filePath);
|
|
199
|
+
if (!transformSet.has(fileReal)) continue;
|
|
200
|
+
for (const [name, base] of nameMap) {
|
|
201
|
+
if (isLeaf(fileReal, name)) continue;
|
|
202
|
+
if (base.kind === "intrinsic") {
|
|
203
|
+
ensureSet(fileReal).add(name);
|
|
204
|
+
changed = true;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const ident = base.ident;
|
|
208
|
+
if (isLeaf(fileReal, ident)) {
|
|
209
|
+
ensureSet(fileReal).add(name);
|
|
210
|
+
changed = true;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (tryResolveAdapterIntrinsic(filePath, ident)) {
|
|
214
|
+
ensureSet(fileReal).add(name);
|
|
215
|
+
changed = true;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (tryResolveImportedLeaf(filePath, ident)) {
|
|
219
|
+
ensureSet(fileReal).add(name);
|
|
220
|
+
changed = true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const globalLeafKeys = /* @__PURE__ */ new Set();
|
|
226
|
+
for (const [file, names] of globalLeaves) for (const name of names) globalLeafKeys.add(`${file}:${name}`);
|
|
227
|
+
return globalLeafKeys;
|
|
228
|
+
}
|
|
229
|
+
function leafKeyExists(defFile, exportedName, allowDefaultFallback, cachedRead, globalLeaves) {
|
|
230
|
+
if (globalLeaves.get(defFile)?.has(exportedName) ?? false) return true;
|
|
231
|
+
if (!allowDefaultFallback) return false;
|
|
232
|
+
const defaultLocalName = findDefaultExportedLocalName(cachedRead(defFile));
|
|
233
|
+
return defaultLocalName ? globalLeaves.get(defFile)?.has(defaultLocalName) ?? false : false;
|
|
234
|
+
}
|
|
235
|
+
function findDefaultExportedLocalName(source) {
|
|
236
|
+
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];
|
|
237
|
+
}
|
|
238
|
+
//#endregion
|
|
239
|
+
export { extractStyledDefBasesFromAstProgram as n, extractStyledDefBasesFromSource as r, computeGlobalLeafKeys as t };
|
package/dist/{extract-external-interface-BgvS5GC0.mjs → extract-external-interface-CdHbvfxu.mjs}
RENAMED
|
@@ -119,9 +119,20 @@ var Logger = class Logger {
|
|
|
119
119
|
}
|
|
120
120
|
static formatContext(context) {
|
|
121
121
|
if (typeof context === "undefined") return null;
|
|
122
|
-
return JSON.stringify(context,
|
|
122
|
+
return JSON.stringify(context, createContextReplacer(), 2);
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
+
function createContextReplacer() {
|
|
126
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
127
|
+
return (key, value) => {
|
|
128
|
+
if (key === "loc" || key === "tokens" || key === "comments" || key === "start" || key === "end") return;
|
|
129
|
+
if (value && typeof value === "object") {
|
|
130
|
+
if (seen.has(value)) return "[Circular]";
|
|
131
|
+
seen.add(value);
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
125
136
|
var LoggerReport = class {
|
|
126
137
|
warnings;
|
|
127
138
|
fileCount;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as toRealPath } from "./path-utils-
|
|
2
|
-
import { r as escapeRegex } from "./string-utils-
|
|
1
|
+
import { n as toRealPath } from "./path-utils-BIpoL4Ue.mjs";
|
|
2
|
+
import { r as escapeRegex } from "./string-utils-DD9wdRHW.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-
|
|
1
|
+
import { a as CollectedWarning, c as MarkerFileContext, l as defineAdapter, n as TransformMode, o as AdapterInput, s as ImportSource } from "./transform-types-DJpFQ5xm.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/run.d.ts
|
|
4
4
|
interface RunTransformOptions {
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { o as assertValidAdapterInput, r as defineAdapter, s as describeValue, t as mergeMarkerDeclarations } from "./merge-markers-
|
|
2
|
-
import { a as Logger, i as resolveBarrelReExport } from "./extract-external-interface-
|
|
3
|
-
import {
|
|
1
|
+
import { o as assertValidAdapterInput, r as defineAdapter, s as describeValue, t as mergeMarkerDeclarations } from "./merge-markers-BC5YNB7D.mjs";
|
|
2
|
+
import { a as Logger, i as resolveBarrelReExport } from "./extract-external-interface-CdHbvfxu.mjs";
|
|
3
|
+
import { r as extractStyledDefBasesFromSource } from "./compute-leaf-set-Drcu2eju.mjs";
|
|
4
|
+
import { n as toRealPath } from "./path-utils-BIpoL4Ue.mjs";
|
|
4
5
|
import jscodeshift from "jscodeshift";
|
|
5
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
7
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -148,7 +149,7 @@ async function runTransform(options) {
|
|
|
148
149
|
const { createModuleResolver } = await import("./resolve-imports-BlxKezSJ.mjs").then((n) => n.n);
|
|
149
150
|
const sharedResolver = createModuleResolver();
|
|
150
151
|
filePaths = orderFilesByLocalImportDependencies(filePaths, sharedResolver, toRealPath);
|
|
151
|
-
const { runPrepass } = await import("./run-prepass-
|
|
152
|
+
const { runPrepass } = await import("./run-prepass-qEr_Mc3y.mjs");
|
|
152
153
|
const absoluteFiles = filePaths.map((f) => resolve(f));
|
|
153
154
|
const absoluteConsumers = consumerFilePaths.map((f) => resolve(f));
|
|
154
155
|
let prepassResult;
|
|
@@ -171,6 +172,7 @@ async function runTransform(options) {
|
|
|
171
172
|
selectorUsages: /* @__PURE__ */ new Map(),
|
|
172
173
|
componentsNeedingMarkerSidecar: /* @__PURE__ */ new Map(),
|
|
173
174
|
componentsNeedingGlobalSelectorBridge: /* @__PURE__ */ new Map(),
|
|
175
|
+
propUsageByFile: /* @__PURE__ */ new Map(),
|
|
174
176
|
globalLeafKeys: leavesOnly ? /* @__PURE__ */ new Set() : void 0
|
|
175
177
|
},
|
|
176
178
|
consumerAnalysis: void 0,
|
|
@@ -197,6 +199,33 @@ async function runTransform(options) {
|
|
|
197
199
|
}
|
|
198
200
|
};
|
|
199
201
|
const lookupAutoExternalInterface = (filePath, componentName) => analysisMap.get(`${toRealPath(filePath)}:${componentName}`);
|
|
202
|
+
const styledDefinitionNamesByFile = /* @__PURE__ */ new Map();
|
|
203
|
+
const resolveExistingSourcePath = (filePath) => {
|
|
204
|
+
for (const ext of [
|
|
205
|
+
"",
|
|
206
|
+
".tsx",
|
|
207
|
+
".ts",
|
|
208
|
+
".jsx",
|
|
209
|
+
".js"
|
|
210
|
+
]) {
|
|
211
|
+
const candidate = `${filePath}${ext}`;
|
|
212
|
+
if (existsSync(candidate)) return candidate;
|
|
213
|
+
}
|
|
214
|
+
return filePath;
|
|
215
|
+
};
|
|
216
|
+
const getStyledDefinitionNames = (filePath) => {
|
|
217
|
+
const realPath = toRealPath(resolveExistingSourcePath(filePath));
|
|
218
|
+
const cached = styledDefinitionNamesByFile.get(realPath);
|
|
219
|
+
if (cached) return cached;
|
|
220
|
+
const extracted = /* @__PURE__ */ new Map();
|
|
221
|
+
extractStyledDefBasesFromSource(realPath, cachedRead(realPath), extracted);
|
|
222
|
+
const names = new Set(extracted.get(realPath)?.keys() ?? []);
|
|
223
|
+
styledDefinitionNamesByFile.set(realPath, names);
|
|
224
|
+
return names;
|
|
225
|
+
};
|
|
226
|
+
const getDefaultExportedName = (filePath) => {
|
|
227
|
+
return cachedRead(toRealPath(resolveExistingSourcePath(filePath))).match(/\bexport\s+default\s+([A-Z][A-Za-z0-9]*)\b/)?.[1] ?? null;
|
|
228
|
+
};
|
|
200
229
|
return {
|
|
201
230
|
...adapterInput,
|
|
202
231
|
externalInterface: (ctx) => {
|
|
@@ -213,9 +242,14 @@ async function runTransform(options) {
|
|
|
213
242
|
const resolvedImport = sharedResolver.resolve(resolve(ctx.filePath), ctx.importSource);
|
|
214
243
|
if (!resolvedImport) return;
|
|
215
244
|
const resolvedPath = toRealPath(resolvedImport);
|
|
216
|
-
const
|
|
217
|
-
if (!transformedFiles.has(toRealPath(
|
|
218
|
-
|
|
245
|
+
const definitionSourcePath = resolveExistingSourcePath(resolveBarrelReExport(resolvedPath, ctx.importedName, prepassResolve, cachedRead) ?? resolvedPath);
|
|
246
|
+
if (!transformedFiles.has(toRealPath(definitionSourcePath))) return;
|
|
247
|
+
const autoInterfaceNames = ctx.importedName === "default" ? [ctx.localName, ctx.importedName] : [ctx.importedName];
|
|
248
|
+
const styledDefinitionNames = getStyledDefinitionNames(definitionSourcePath);
|
|
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;
|
|
252
|
+
return autoInterfaceNames.map((name) => lookupAutoExternalInterface(definitionSourcePath, name)).find((result) => result !== void 0)?.styles ? { acceptsSx: true } : void 0;
|
|
219
253
|
}
|
|
220
254
|
};
|
|
221
255
|
}
|
|
@@ -275,7 +309,7 @@ async function runTransform(options) {
|
|
|
275
309
|
const result = await runTransformSequentially(transformModule, filePaths, runnerOptions);
|
|
276
310
|
if (sidecarFiles.size > 0 && !dryRun) for (const [sidecarPath, content] of sidecarFiles) await writeFile(sidecarPath, mergeSidecarContent(sidecarPath, content), "utf-8");
|
|
277
311
|
if (bridgeResults.size > 0 && !dryRun) {
|
|
278
|
-
const { buildConsumerReplacements, patchConsumerFile } = await import("./bridge-consumer-patcher-
|
|
312
|
+
const { buildConsumerReplacements, patchConsumerFile } = await import("./bridge-consumer-patcher-31jI1854.mjs");
|
|
279
313
|
const consumerReplacements = buildConsumerReplacements(crossFilePrepassResult.selectorUsages, bridgeResults, transformedFiles);
|
|
280
314
|
const patchedFiles = [];
|
|
281
315
|
for (const [consumerPath, replacements] of consumerReplacements) {
|
|
@@ -288,7 +322,7 @@ async function runTransform(options) {
|
|
|
288
322
|
if (formatterCommands && patchedFiles.length > 0) await runFormatters(formatterCommands, patchedFiles);
|
|
289
323
|
}
|
|
290
324
|
if (prepassResult.forwardedAsConsumers.size > 0 && !dryRun) {
|
|
291
|
-
const { buildForwardedAsReplacements, patchConsumerForwardedAs } = await import("./forwarded-as-consumer-patcher-
|
|
325
|
+
const { buildForwardedAsReplacements, patchConsumerForwardedAs } = await import("./forwarded-as-consumer-patcher-BYCrqzRm.mjs");
|
|
292
326
|
const forwardedAsReplacements = buildForwardedAsReplacements(prepassResult.forwardedAsConsumers, transformedFiles);
|
|
293
327
|
const patchedFiles = [];
|
|
294
328
|
for (const [consumerPath, entries] of forwardedAsReplacements) {
|
|
@@ -301,7 +335,7 @@ async function runTransform(options) {
|
|
|
301
335
|
if (formatterCommands && patchedFiles.length > 0) await runFormatters(formatterCommands, patchedFiles);
|
|
302
336
|
}
|
|
303
337
|
if (transientPropRenames.size > 0 && !dryRun) {
|
|
304
|
-
const { collectTransientPropPatches } = await import("./transient-prop-consumer-patcher-
|
|
338
|
+
const { collectTransientPropPatches } = await import("./transient-prop-consumer-patcher-DdIYPSFk.mjs");
|
|
305
339
|
const patches = collectTransientPropPatches({
|
|
306
340
|
transientPropRenames,
|
|
307
341
|
consumerFilePaths: consumerFilePaths.map((p) => resolve(p)),
|
|
@@ -55,6 +55,7 @@ function assertAdapterShape(candidate, where, allowAutoExtIf) {
|
|
|
55
55
|
"",
|
|
56
56
|
"resolveSelector(context) is called with:",
|
|
57
57
|
" - { kind: \"selectorInterpolation\", importedName, source, path? }",
|
|
58
|
+
" - { kind: \"mediaQueryInterpolation\", importedName, source, path?, mediaQuery }",
|
|
58
59
|
"",
|
|
59
60
|
`Docs/examples: ${ADAPTER_DOCS_URL}`
|
|
60
61
|
].join("\n"));
|
|
@@ -250,6 +251,8 @@ const DEFAULT_THEME_HOOK = {
|
|
|
250
251
|
* // - { kind: "media", expr, imports } for media queries (e.g., breakpoints.phone)
|
|
251
252
|
* // - { kind: "pseudoAlias", values, styleSelectorExpr?, imports? } for pseudo-class expansion
|
|
252
253
|
* // - undefined to bail/skip the file
|
|
254
|
+
* // For @media placeholders, check ctx.kind === "mediaQueryInterpolation" and
|
|
255
|
+
* // use ctx.mediaQuery.feature to choose the correct defineConsts media key.
|
|
253
256
|
* void ctx;
|
|
254
257
|
* },
|
|
255
258
|
*
|
|
@@ -292,24 +295,98 @@ function defineAdapter(adapter) {
|
|
|
292
295
|
const MARKER_BLOCK_RE = /(?:\/\*\*[^]*?\*\/\n)?export const \w+ = stylex\.defineMarker\(\);/gm;
|
|
293
296
|
/** Regex matching just the export line (used for dedup checks). */
|
|
294
297
|
const MARKER_EXPORT_RE = /^export const \w+ = stylex\.defineMarker\(\);$/gm;
|
|
298
|
+
/** Regex matching a generated defineVars export block. */
|
|
299
|
+
const DEFINE_VARS_BLOCK_RE = /export const \w+ = stylex\.defineVars\(\{\n[\s\S]*?\n\}\);/gm;
|
|
300
|
+
/** Regex matching just the defineVars export line (used for dedup checks). */
|
|
301
|
+
const DEFINE_VARS_EXPORT_RE = /^export const \w+ = stylex\.defineVars\(\{$/gm;
|
|
295
302
|
/**
|
|
296
303
|
* Merge marker declarations from `incoming` into `base`, appending only new
|
|
297
304
|
* marker blocks (JSDoc + export). Returns `base` unchanged if all markers already exist.
|
|
298
305
|
*/
|
|
299
306
|
function mergeMarkerDeclarations(base, incoming) {
|
|
300
|
-
const
|
|
301
|
-
|
|
307
|
+
const mergedDefineVars = mergeDefineVarsBlocks(base, incoming);
|
|
308
|
+
const markerBlocks = getNewBlocks({
|
|
309
|
+
base: mergedDefineVars,
|
|
310
|
+
incoming,
|
|
311
|
+
blockRegex: MARKER_BLOCK_RE,
|
|
312
|
+
exportRegex: MARKER_EXPORT_RE
|
|
313
|
+
});
|
|
314
|
+
const defineVarsBlocks = getNewBlocks({
|
|
315
|
+
base: mergedDefineVars,
|
|
316
|
+
incoming,
|
|
317
|
+
blockRegex: DEFINE_VARS_BLOCK_RE,
|
|
318
|
+
exportRegex: DEFINE_VARS_EXPORT_RE
|
|
319
|
+
});
|
|
320
|
+
const blocksToAdd = [...markerBlocks, ...defineVarsBlocks];
|
|
321
|
+
if (blocksToAdd.length === 0) return mergedDefineVars;
|
|
322
|
+
let merged = mergedDefineVars;
|
|
323
|
+
if (!merged.includes("@stylexjs/stylex")) merged = `import * as stylex from "@stylexjs/stylex";\n\n${merged}`;
|
|
324
|
+
return merged.trimEnd() + "\n\n" + blocksToAdd.join("\n\n") + "\n";
|
|
325
|
+
}
|
|
326
|
+
function getNewBlocks(args) {
|
|
327
|
+
const { base, incoming, blockRegex, exportRegex } = args;
|
|
328
|
+
const incomingExports = [...incoming.matchAll(exportRegex)].map((m) => m[0]);
|
|
329
|
+
if (incomingExports.length === 0) return [];
|
|
302
330
|
const newExportLines = incomingExports.filter((line) => !base.includes(line));
|
|
303
|
-
if (newExportLines.length === 0) return
|
|
331
|
+
if (newExportLines.length === 0) return [];
|
|
304
332
|
const newExportSet = new Set(newExportLines);
|
|
305
|
-
|
|
306
|
-
const exportLine = block.match(
|
|
333
|
+
return [...incoming.matchAll(blockRegex)].map((m) => m[0]).filter((block) => {
|
|
334
|
+
const exportLine = block.match(exportRegex);
|
|
307
335
|
return exportLine && newExportSet.has(exportLine[0]);
|
|
308
336
|
});
|
|
309
|
-
|
|
337
|
+
}
|
|
338
|
+
function mergeDefineVarsBlocks(base, incoming) {
|
|
310
339
|
let merged = base;
|
|
311
|
-
|
|
312
|
-
|
|
340
|
+
for (const incomingBlock of incoming.matchAll(DEFINE_VARS_BLOCK_RE)) {
|
|
341
|
+
const incomingText = incomingBlock[0];
|
|
342
|
+
const exportName = readDefineVarsExportName(incomingText);
|
|
343
|
+
if (!exportName) continue;
|
|
344
|
+
const existingBlock = findDefineVarsBlockByExportName(merged, exportName);
|
|
345
|
+
if (!existingBlock) continue;
|
|
346
|
+
const entriesToAdd = getMissingDefineVarsEntries({
|
|
347
|
+
existingBlock: existingBlock.text,
|
|
348
|
+
incomingBlock: incomingText
|
|
349
|
+
});
|
|
350
|
+
if (entriesToAdd.length === 0) continue;
|
|
351
|
+
const insertionPoint = existingBlock.start + existingBlock.text.lastIndexOf("\n});");
|
|
352
|
+
const linesToAdd = entriesToAdd.map((entry) => entry.line);
|
|
353
|
+
merged = `${merged.slice(0, insertionPoint)}\n${linesToAdd.join("\n")}${merged.slice(insertionPoint)}`;
|
|
354
|
+
}
|
|
355
|
+
return merged;
|
|
356
|
+
}
|
|
357
|
+
function readDefineVarsExportName(block) {
|
|
358
|
+
return /^export const ([A-Za-z_$][\w$]*) = stylex\.defineVars\(\{/m.exec(block)?.[1] ?? null;
|
|
359
|
+
}
|
|
360
|
+
function findDefineVarsBlockByExportName(source, exportName) {
|
|
361
|
+
for (const match of source.matchAll(DEFINE_VARS_BLOCK_RE)) {
|
|
362
|
+
const text = match[0];
|
|
363
|
+
if (readDefineVarsExportName(text) === exportName && match.index !== void 0) return {
|
|
364
|
+
text,
|
|
365
|
+
start: match.index
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
function getMissingDefineVarsEntries(args) {
|
|
371
|
+
const { existingBlock, incomingBlock } = args;
|
|
372
|
+
const existingKeys = new Set(readDefineVarsEntryKeys(existingBlock));
|
|
373
|
+
return readDefineVarsEntries(incomingBlock).filter((entry) => !existingKeys.has(entry.key));
|
|
374
|
+
}
|
|
375
|
+
function readDefineVarsEntryKeys(block) {
|
|
376
|
+
return readDefineVarsEntries(block).map((entry) => entry.key);
|
|
377
|
+
}
|
|
378
|
+
function readDefineVarsEntries(block) {
|
|
379
|
+
return block.split("\n").map((line) => ({
|
|
380
|
+
line,
|
|
381
|
+
match: /^\s*(?:(["']--[^"']+["'])|([A-Za-z_$][\w$]*))\s*:/.exec(line)
|
|
382
|
+
})).filter((entry) => Boolean(entry.match)).map(({ line, match }) => ({
|
|
383
|
+
key: normalizeDefineVarsEntryKey(match[1] ?? match[2]),
|
|
384
|
+
line
|
|
385
|
+
}));
|
|
386
|
+
}
|
|
387
|
+
function normalizeDefineVarsEntryKey(key) {
|
|
388
|
+
if (key.length >= 2 && (key.startsWith("\"") && key.endsWith("\"") || key.startsWith("'") && key.endsWith("'"))) return key.slice(1, -1);
|
|
389
|
+
return key;
|
|
313
390
|
}
|
|
314
391
|
//#endregion
|
|
315
392
|
export { assertValidAdapter as a, isDirectionalResult as i, DEFAULT_THEME_HOOK as n, assertValidAdapterInput as o, defineAdapter as r, describeValue as s, mergeMarkerDeclarations as t };
|