styled-components-to-stylex-codemod 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as ImportSource, i as AdapterInput, o as MarkerFileContext, s as defineAdapter, t as CollectedWarning } from "./logger-xD1SimCA.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/run.d.ts
|
|
4
4
|
interface RunTransformOptions {
|
|
@@ -107,4 +107,4 @@ interface RunTransformResult {
|
|
|
107
107
|
*/
|
|
108
108
|
declare function runTransform(options: RunTransformOptions): Promise<RunTransformResult>;
|
|
109
109
|
//#endregion
|
|
110
|
-
export { type AdapterInput, defineAdapter, runTransform };
|
|
110
|
+
export { type AdapterInput, type ImportSource, type MarkerFileContext, defineAdapter, runTransform };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as assertValidAdapterInput, r as defineAdapter, s as describeValue, t as mergeMarkerDeclarations } from "./merge-markers-B58_cRdA.mjs";
|
|
2
2
|
import { t as Logger } from "./logger-C2O81VeU.mjs";
|
|
3
3
|
import { run } from "jscodeshift/src/Runner.js";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -204,7 +204,8 @@ async function runTransform(options) {
|
|
|
204
204
|
resolveCall: resolveCallWithLogging,
|
|
205
205
|
resolveSelector: resolveSelectorWithLogging,
|
|
206
206
|
resolveBaseComponent: adapterInput.resolveBaseComponent ? resolveBaseComponentWithLogging : void 0,
|
|
207
|
-
resolveThemeCall: resolvedAdapter.resolveThemeCall
|
|
207
|
+
resolveThemeCall: resolvedAdapter.resolveThemeCall,
|
|
208
|
+
markerFile: resolvedAdapter.markerFile
|
|
208
209
|
};
|
|
209
210
|
const transformPath = (() => {
|
|
210
211
|
const adjacent = join(__dirname, "transform.mjs");
|
|
@@ -307,10 +308,6 @@ function createAutoPrepassFailureError(err, consumerPatterns, parser) {
|
|
|
307
308
|
/**
|
|
308
309
|
* Merge new sidecar marker content into an existing .stylex.ts file, preserving
|
|
309
310
|
* user-owned exports (e.g. defineVars). If the file doesn't exist, returns content as-is.
|
|
310
|
-
*
|
|
311
|
-
* New marker declarations (`export const XMarker = stylex.defineMarker()`) are
|
|
312
|
-
* appended only if they don't already exist in the file. The stylex import is
|
|
313
|
-
* ensured at the top.
|
|
314
311
|
*/
|
|
315
312
|
function mergeSidecarContent(sidecarPath, newContent) {
|
|
316
313
|
let existing;
|
|
@@ -319,17 +316,7 @@ function mergeSidecarContent(sidecarPath, newContent) {
|
|
|
319
316
|
} catch {
|
|
320
317
|
return newContent;
|
|
321
318
|
}
|
|
322
|
-
|
|
323
|
-
const newMarkers = [];
|
|
324
|
-
for (const m of newContent.matchAll(markerLineRe)) newMarkers.push(m[0]);
|
|
325
|
-
if (newMarkers.length === 0) return newContent;
|
|
326
|
-
const markersToAdd = newMarkers.filter((line) => !existing.includes(line));
|
|
327
|
-
if (markersToAdd.length === 0) return existing;
|
|
328
|
-
let merged = existing;
|
|
329
|
-
if (!merged.includes("@stylexjs/stylex")) merged = `import * as stylex from "@stylexjs/stylex";\n\n${merged}`;
|
|
330
|
-
const trailingNewline = merged.endsWith("\n") ? "" : "\n";
|
|
331
|
-
merged = merged + trailingNewline + markersToAdd.join("\n") + "\n";
|
|
332
|
-
return merged;
|
|
319
|
+
return mergeMarkerDeclarations(existing, newContent);
|
|
333
320
|
}
|
|
334
321
|
/** Run formatter commands on a list of files, logging warnings on failure. */
|
|
335
322
|
async function runFormatters(commands, files) {
|
|
@@ -500,6 +500,10 @@ type ExternalInterfaceResult = {
|
|
|
500
500
|
elementProps?: boolean; /** Whether cross-file consumers use JSX spread ({...props}) */
|
|
501
501
|
spreadProps?: boolean;
|
|
502
502
|
};
|
|
503
|
+
interface MarkerFileContext {
|
|
504
|
+
/** Absolute path of the file being transformed */
|
|
505
|
+
filePath: string;
|
|
506
|
+
}
|
|
503
507
|
/**
|
|
504
508
|
* Configuration for a custom style merger function that combines stylex.props()
|
|
505
509
|
* results with external className/style props.
|
|
@@ -659,6 +663,22 @@ interface Adapter {
|
|
|
659
663
|
* @default false
|
|
660
664
|
*/
|
|
661
665
|
usePhysicalProperties?: boolean;
|
|
666
|
+
/**
|
|
667
|
+
* Optional function to customize where marker sidecar files (`stylex.defineMarker()`)
|
|
668
|
+
* are written. By default, markers are placed in a `.stylex.ts` file next to the source.
|
|
669
|
+
*
|
|
670
|
+
* When provided, the function receives the source file path and returns an `ImportSource`
|
|
671
|
+
* that determines both the import path in the transformed file and the file path where
|
|
672
|
+
* markers are written.
|
|
673
|
+
*
|
|
674
|
+
* Example:
|
|
675
|
+
* ```typescript
|
|
676
|
+
* markerFile(ctx) {
|
|
677
|
+
* return { kind: "absolutePath", value: "/path/to/shared/markers.stylex.ts" };
|
|
678
|
+
* }
|
|
679
|
+
* ```
|
|
680
|
+
*/
|
|
681
|
+
markerFile?: (context: MarkerFileContext) => ImportSource;
|
|
662
682
|
}
|
|
663
683
|
/**
|
|
664
684
|
* User-facing adapter input type accepted by `defineAdapter()`.
|
|
@@ -686,6 +706,7 @@ interface AdapterInput {
|
|
|
686
706
|
themeHook?: Adapter["themeHook"];
|
|
687
707
|
useSxProp: Adapter["useSxProp"];
|
|
688
708
|
usePhysicalProperties?: Adapter["usePhysicalProperties"];
|
|
709
|
+
markerFile?: Adapter["markerFile"];
|
|
689
710
|
}
|
|
690
711
|
/**
|
|
691
712
|
* Helper for nicer user authoring + type inference.
|
|
@@ -777,4 +798,4 @@ interface CollectedWarning extends WarningLog {
|
|
|
777
798
|
filePath: string;
|
|
778
799
|
}
|
|
779
800
|
//#endregion
|
|
780
|
-
export {
|
|
801
|
+
export { ImportSource as a, AdapterInput as i, WarningLog as n, MarkerFileContext as o, Adapter as r, defineAdapter as s, CollectedWarning as t };
|
|
@@ -133,6 +133,14 @@ function assertAdapterShape(candidate, where, allowAutoExtIf) {
|
|
|
133
133
|
absolutePathExample: "/path/to/module.ts"
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
+
const markerFile = obj?.markerFile;
|
|
137
|
+
if (markerFile !== void 0 && markerFile !== null && typeof markerFile !== "function") throw new Error([
|
|
138
|
+
`${where}: adapter.markerFile must be a function when provided.`,
|
|
139
|
+
`Received: markerFile=${describeValue(markerFile)}`,
|
|
140
|
+
"",
|
|
141
|
+
"Expected signature:",
|
|
142
|
+
" markerFile(ctx: { filePath: string }) => { kind: \"specifier\" | \"absolutePath\", value: string }"
|
|
143
|
+
].join("\n"));
|
|
136
144
|
const themeHook = obj?.themeHook;
|
|
137
145
|
if (themeHook !== null && themeHook !== void 0) {
|
|
138
146
|
if (typeof themeHook !== "object") throw new Error([
|
|
@@ -269,4 +277,33 @@ function defineAdapter(adapter) {
|
|
|
269
277
|
return adapter;
|
|
270
278
|
}
|
|
271
279
|
//#endregion
|
|
272
|
-
|
|
280
|
+
//#region src/internal/merge-markers.ts
|
|
281
|
+
/**
|
|
282
|
+
* Shared utility for merging marker sidecar content.
|
|
283
|
+
* Core concepts: deduplication of defineMarker declarations across files.
|
|
284
|
+
*/
|
|
285
|
+
/** Regex matching a marker block: optional JSDoc comment followed by the export line. */
|
|
286
|
+
const MARKER_BLOCK_RE = /(?:\/\*\*[^]*?\*\/\n)?export const \w+ = stylex\.defineMarker\(\);/gm;
|
|
287
|
+
/** Regex matching just the export line (used for dedup checks). */
|
|
288
|
+
const MARKER_EXPORT_RE = /^export const \w+ = stylex\.defineMarker\(\);$/gm;
|
|
289
|
+
/**
|
|
290
|
+
* Merge marker declarations from `incoming` into `base`, appending only new
|
|
291
|
+
* marker blocks (JSDoc + export). Returns `base` unchanged if all markers already exist.
|
|
292
|
+
*/
|
|
293
|
+
function mergeMarkerDeclarations(base, incoming) {
|
|
294
|
+
const incomingExports = [...incoming.matchAll(MARKER_EXPORT_RE)].map((m) => m[0]);
|
|
295
|
+
if (incomingExports.length === 0) return base;
|
|
296
|
+
const newExportLines = incomingExports.filter((line) => !base.includes(line));
|
|
297
|
+
if (newExportLines.length === 0) return base;
|
|
298
|
+
const newExportSet = new Set(newExportLines);
|
|
299
|
+
const blocksToAdd = [...incoming.matchAll(MARKER_BLOCK_RE)].map((m) => m[0]).filter((block) => {
|
|
300
|
+
const exportLine = block.match(MARKER_EXPORT_RE);
|
|
301
|
+
return exportLine && newExportSet.has(exportLine[0]);
|
|
302
|
+
});
|
|
303
|
+
if (blocksToAdd.length === 0) return base;
|
|
304
|
+
let merged = base;
|
|
305
|
+
if (!merged.includes("@stylexjs/stylex")) merged = `import * as stylex from "@stylexjs/stylex";\n\n${merged}`;
|
|
306
|
+
return merged.trimEnd() + "\n\n" + blocksToAdd.join("\n\n") + "\n";
|
|
307
|
+
}
|
|
308
|
+
//#endregion
|
|
309
|
+
export { assertValidAdapter as a, isDirectionalResult as i, DEFAULT_THEME_HOOK as n, assertValidAdapterInput as o, defineAdapter as r, describeValue as s, mergeMarkerDeclarations as t };
|
package/dist/transform.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as WarningLog, r as Adapter } from "./logger-
|
|
1
|
+
import { n as WarningLog, r as Adapter } from "./logger-xD1SimCA.mjs";
|
|
2
2
|
import { API, FileInfo, Options } from "jscodeshift";
|
|
3
3
|
|
|
4
4
|
//#region src/internal/transform-types.d.ts
|
|
@@ -10,6 +10,8 @@ interface TransformResult {
|
|
|
10
10
|
warnings: WarningLog[];
|
|
11
11
|
/** Content for the sidecar .stylex.ts file (defineMarker declarations). Undefined when no markers needed. */
|
|
12
12
|
sidecarContent?: string;
|
|
13
|
+
/** Absolute file path for the sidecar file, when adapter.markerFile provides a custom location. */
|
|
14
|
+
sidecarFilePath?: string;
|
|
13
15
|
/** Bridge components emitted for unconverted consumer selectors. */
|
|
14
16
|
bridgeResults?: BridgeComponentResult[];
|
|
15
17
|
/** Transient prop renames for exported components, keyed by export name. */
|
package/dist/transform.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as assertValidAdapter, i as isDirectionalResult, n as DEFAULT_THEME_HOOK, t as mergeMarkerDeclarations } from "./merge-markers-B58_cRdA.mjs";
|
|
2
2
|
import { t as Logger } from "./logger-C2O81VeU.mjs";
|
|
3
3
|
import { a as isValidIdentifierName, c as lowerFirst, i as isPrettierIgnoreComment, l as normalizeWhitespace, n as escapeRegex, o as kebabToCamelCase, r as isBackgroundImageValue, s as looksLikeLength, t as capitalize, u as sanitizeIdentifier } from "./string-utils-5EMAWj3q.mjs";
|
|
4
4
|
import { n as parseStyledTemplateLiteral, t as PLACEHOLDER_RE } from "./styled-css-C3QKH6Od.mjs";
|
|
5
5
|
import { t as toRealPath } from "./path-utils-BlOXGcCF.mjs";
|
|
6
|
-
import path, { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
import path, { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
7
7
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
8
8
|
import valueParser from "postcss-value-parser";
|
|
9
9
|
import { compile } from "stylis";
|
|
@@ -1412,6 +1412,8 @@ var TransformContext = class {
|
|
|
1412
1412
|
ancestorAttrsByStyleKey;
|
|
1413
1413
|
/** Content for the sidecar .stylex.ts file (defineMarker declarations), populated by emitStylesStep */
|
|
1414
1414
|
sidecarStylexContent;
|
|
1415
|
+
/** Absolute file path for the sidecar file, when adapter.markerFile provides a custom location */
|
|
1416
|
+
sidecarFilePath;
|
|
1415
1417
|
/** Bridge components emitted for unconverted consumer selectors. */
|
|
1416
1418
|
bridgeResults;
|
|
1417
1419
|
/** Transient prop renames for exported components (for consumer patching). */
|
|
@@ -4973,7 +4975,13 @@ function collectStyledDefaultImportLocalNames(styledImports) {
|
|
|
4973
4975
|
const styledLocalNames = /* @__PURE__ */ new Set();
|
|
4974
4976
|
styledImports.forEach((imp) => {
|
|
4975
4977
|
const specs = imp.node.specifiers ?? [];
|
|
4976
|
-
for (const spec of specs)
|
|
4978
|
+
for (const spec of specs) {
|
|
4979
|
+
if (spec.type === "ImportDefaultSpecifier" && spec.local?.type === "Identifier") {
|
|
4980
|
+
styledLocalNames.add(spec.local.name);
|
|
4981
|
+
continue;
|
|
4982
|
+
}
|
|
4983
|
+
if (spec.type === "ImportSpecifier" && spec.imported?.type === "Identifier" && spec.imported.name === "styled" && spec.local?.type === "Identifier") styledLocalNames.add(spec.local.name);
|
|
4984
|
+
}
|
|
4977
4985
|
});
|
|
4978
4986
|
return styledLocalNames;
|
|
4979
4987
|
}
|
|
@@ -7202,7 +7210,8 @@ function collectStyledDeclsStep(ctx) {
|
|
|
7202
7210
|
const { styledImports, root, j, cssLocal } = ctx;
|
|
7203
7211
|
if (!styledImports) return CONTINUE;
|
|
7204
7212
|
const styledDefaultSpecifier = styledImports.find(j.ImportDefaultSpecifier).nodes()[0];
|
|
7205
|
-
const
|
|
7213
|
+
const namedStyledSpecifier = !styledDefaultSpecifier ? styledImports.find(j.ImportSpecifier).filter((p) => p.node.imported?.type === "Identifier" && p.node.imported.name === "styled").nodes()[0] : void 0;
|
|
7214
|
+
const styledDefaultImport = styledDefaultSpecifier?.local?.type === "Identifier" ? styledDefaultSpecifier.local.name : namedStyledSpecifier?.local?.type === "Identifier" ? namedStyledSpecifier.local.name : void 0;
|
|
7206
7215
|
ctx.styledDefaultImport = styledDefaultImport;
|
|
7207
7216
|
if (extractStyledCallArgs({
|
|
7208
7217
|
root,
|
|
@@ -7708,18 +7717,20 @@ function tryHandleAnimation(args) {
|
|
|
7708
7717
|
timeSlots.sort((a, b) => a.originalIndex - b.originalIndex);
|
|
7709
7718
|
for (let i = tokens.length - 1; i >= 0; i--) if (INTERPOLATED_TIME_RE.test(tokens[i])) tokens.splice(i, 1);
|
|
7710
7719
|
const classified = classifyAnimationTokens(tokens);
|
|
7711
|
-
|
|
7712
|
-
|
|
7720
|
+
let durationValue = null;
|
|
7721
|
+
let delayValue = null;
|
|
7713
7722
|
for (let i = 0; i < timeSlots.length && i < 2; i++) {
|
|
7714
7723
|
const slot = timeSlots[i];
|
|
7715
7724
|
const longhand = i === 0 ? "animationDuration" : "animationDelay";
|
|
7716
|
-
if (slot.kind === "static") if (longhand === "animationDuration")
|
|
7717
|
-
else
|
|
7725
|
+
if (slot.kind === "static") if (longhand === "animationDuration") durationValue = slot.value;
|
|
7726
|
+
else delayValue = slot.value;
|
|
7718
7727
|
else {
|
|
7728
|
+
const expr = decl.templateExpressions[slot.slotId];
|
|
7719
7729
|
const fallbackValue = computeInterpolatedTimeFallback(decl, slot.slotId, slot.unit);
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7730
|
+
const timeValue = buildInterpolatedTimeExpression(j, decl, slot.slotId, slot.unit) ?? fallbackValue ?? `0${slot.unit}`;
|
|
7731
|
+
if (longhand === "animationDuration") durationValue = timeValue;
|
|
7732
|
+
else delayValue = timeValue;
|
|
7733
|
+
if (expr?.type === "ArrowFunctionExpression") interpolatedAnimTimes.push({
|
|
7723
7734
|
slotId: slot.slotId,
|
|
7724
7735
|
unit: slot.unit,
|
|
7725
7736
|
longhand,
|
|
@@ -7728,8 +7739,8 @@ function tryHandleAnimation(args) {
|
|
|
7728
7739
|
});
|
|
7729
7740
|
}
|
|
7730
7741
|
}
|
|
7731
|
-
durations.push(
|
|
7732
|
-
delays.push(
|
|
7742
|
+
durations.push(durationValue);
|
|
7743
|
+
delays.push(delayValue);
|
|
7733
7744
|
timings.push(classified.timing);
|
|
7734
7745
|
directions.push(classified.direction);
|
|
7735
7746
|
fillModes.push(classified.fillMode);
|
|
@@ -7748,7 +7759,7 @@ function tryHandleAnimation(args) {
|
|
|
7748
7759
|
if (animNames.length === 1 && firstAnim && firstAnim.kind === "ident") applyProp("animationName", j.identifier(firstAnim.name), null);
|
|
7749
7760
|
else applyProp("animationName", buildCommaTemplate(animNames), null);
|
|
7750
7761
|
const anyValues = (values) => values.some((value) => value !== null);
|
|
7751
|
-
const joinWithDefaults = (values, fallback) =>
|
|
7762
|
+
const joinWithDefaults = (values, fallback) => buildCommaSeparatedValues(j, values, fallback);
|
|
7752
7763
|
if (anyValues(durations)) applyProp("animationDuration", joinWithDefaults(durations, "0s"), null);
|
|
7753
7764
|
if (anyValues(timings)) applyProp("animationTimingFunction", joinWithDefaults(timings, "ease"), null);
|
|
7754
7765
|
if (anyValues(delays)) applyProp("animationDelay", joinWithDefaults(delays, "0s"), null);
|
|
@@ -7762,6 +7773,36 @@ function tryHandleAnimation(args) {
|
|
|
7762
7773
|
}
|
|
7763
7774
|
return false;
|
|
7764
7775
|
}
|
|
7776
|
+
function buildCommaSeparatedValues(j, values, fallback) {
|
|
7777
|
+
const parts = values.map((value) => value ?? fallback);
|
|
7778
|
+
if (parts.length === 1) {
|
|
7779
|
+
const first = parts[0];
|
|
7780
|
+
return typeof first === "string" ? first : cloneAstNode(first);
|
|
7781
|
+
}
|
|
7782
|
+
const quasis = [];
|
|
7783
|
+
const exprs = [];
|
|
7784
|
+
let text = "";
|
|
7785
|
+
for (let i = 0; i < parts.length; i++) {
|
|
7786
|
+
if (i > 0) text += ", ";
|
|
7787
|
+
const part = parts[i];
|
|
7788
|
+
if (typeof part === "string") {
|
|
7789
|
+
text += part;
|
|
7790
|
+
continue;
|
|
7791
|
+
}
|
|
7792
|
+
quasis.push(j.templateElement({
|
|
7793
|
+
raw: text,
|
|
7794
|
+
cooked: text
|
|
7795
|
+
}, false));
|
|
7796
|
+
exprs.push(cloneAstNode(part));
|
|
7797
|
+
text = "";
|
|
7798
|
+
}
|
|
7799
|
+
if (exprs.length === 0) return text;
|
|
7800
|
+
quasis.push(j.templateElement({
|
|
7801
|
+
raw: text,
|
|
7802
|
+
cooked: text
|
|
7803
|
+
}, true));
|
|
7804
|
+
return j.templateLiteral(quasis, exprs);
|
|
7805
|
+
}
|
|
7765
7806
|
/** Matches placeholder tokens with optional time unit suffix (e.g., `__SC_EXPR_1__ms`). */
|
|
7766
7807
|
const INTERPOLATED_TIME_RE = /^__SC_EXPR_(\d+)__(ms|s)$/;
|
|
7767
7808
|
/** Matches any placeholder token (with or without suffix) to exclude from timeline detection. */
|
|
@@ -7780,6 +7821,13 @@ function computeInterpolatedTimeFallback(decl, slotId, unit) {
|
|
|
7780
7821
|
}
|
|
7781
7822
|
return null;
|
|
7782
7823
|
}
|
|
7824
|
+
function buildInterpolatedTimeExpression(j, decl, slotId, unit) {
|
|
7825
|
+
const expr = decl.templateExpressions[slotId];
|
|
7826
|
+
if (!expr || expr.type === "ArrowFunctionExpression") return null;
|
|
7827
|
+
const staticVal = literalToStaticValue(expr);
|
|
7828
|
+
if (staticVal !== null) return j.stringLiteral(`${staticVal}${unit}`);
|
|
7829
|
+
return buildTemplateWithStaticParts(j, cloneAstNode(expr), "", unit);
|
|
7830
|
+
}
|
|
7783
7831
|
/**
|
|
7784
7832
|
* Emits dynamic style functions for interpolated animation time tokens.
|
|
7785
7833
|
* For each interpolated token, creates a style function like:
|
|
@@ -7873,8 +7921,20 @@ function buildMultiAnimationCallArg(j, interpSegments, valuesList, defaultFallba
|
|
|
7873
7921
|
}, false));
|
|
7874
7922
|
exprs.push(interp.expr);
|
|
7875
7923
|
prefix = interp.unit;
|
|
7876
|
-
} else
|
|
7924
|
+
} else {
|
|
7925
|
+
const value = valuesList[i] ?? defaultFallback;
|
|
7926
|
+
if (typeof value === "string") prefix += value;
|
|
7927
|
+
else {
|
|
7928
|
+
quasis.push(j.templateElement({
|
|
7929
|
+
raw: prefix,
|
|
7930
|
+
cooked: prefix
|
|
7931
|
+
}, false));
|
|
7932
|
+
exprs.push(cloneAstNode(value));
|
|
7933
|
+
prefix = "";
|
|
7934
|
+
}
|
|
7935
|
+
}
|
|
7877
7936
|
}
|
|
7937
|
+
if (exprs.length === 0) return prefix;
|
|
7878
7938
|
quasis.push(j.templateElement({
|
|
7879
7939
|
raw: prefix,
|
|
7880
7940
|
cooked: prefix
|
|
@@ -7887,10 +7947,19 @@ function convertStyledKeyframes(args) {
|
|
|
7887
7947
|
return convertStyledKeyframesImpl(args);
|
|
7888
7948
|
}
|
|
7889
7949
|
function parseKeyframesTemplate(args) {
|
|
7890
|
-
const { template } = args;
|
|
7950
|
+
const { template, j, scopePath } = args;
|
|
7891
7951
|
if (!template || template.type !== "TemplateLiteral") return null;
|
|
7892
|
-
|
|
7893
|
-
|
|
7952
|
+
const slotExprById = /* @__PURE__ */ new Map();
|
|
7953
|
+
for (let i = 0; i < (template.expressions?.length ?? 0); i++) {
|
|
7954
|
+
const expr = template.expressions[i];
|
|
7955
|
+
if (!expr) return null;
|
|
7956
|
+
if (!isStaticSafeKeyframesSlotExpression(expr, scopePath)) return null;
|
|
7957
|
+
slotExprById.set(i, expr);
|
|
7958
|
+
}
|
|
7959
|
+
const ast = compile(`@keyframes __SC_KEYFRAMES__ { ${(template.quasis ?? []).map((q, i) => {
|
|
7960
|
+
const raw = q.value?.raw ?? "";
|
|
7961
|
+
return i < (template.expressions?.length ?? 0) ? `${raw}__SC_EXPR_${i}__` : raw;
|
|
7962
|
+
}).join("")} }`);
|
|
7894
7963
|
const frames = {};
|
|
7895
7964
|
const visit = (node) => {
|
|
7896
7965
|
if (!node) return;
|
|
@@ -7911,7 +7980,10 @@ function parseKeyframesTemplate(args) {
|
|
|
7911
7980
|
const propRaw = typeof c.props === "string" && c.props ? c.props : typeof c.value === "string" && c.value.includes(":") ? (c.value.split(":")[0] ?? "").trim() : "";
|
|
7912
7981
|
const valueRaw = typeof c.children === "string" ? c.children.trim() : typeof c.value === "string" && c.value.includes(":") ? c.value.split(":").slice(1).join(":").replace(/;$/, "").trim() : "";
|
|
7913
7982
|
if (!propRaw) continue;
|
|
7914
|
-
applyStaticDeclsToStyleObj(styleObj, propRaw.trim(), valueRaw
|
|
7983
|
+
applyStaticDeclsToStyleObj(styleObj, propRaw.trim(), valueRaw, {
|
|
7984
|
+
j,
|
|
7985
|
+
slotExprById
|
|
7986
|
+
});
|
|
7915
7987
|
}
|
|
7916
7988
|
frames[frameKey] = styleObj;
|
|
7917
7989
|
return;
|
|
@@ -7931,7 +8003,11 @@ function convertStyledKeyframesImpl(args) {
|
|
|
7931
8003
|
if (p.node.id.type !== "Identifier") return;
|
|
7932
8004
|
const localName = p.node.id.name;
|
|
7933
8005
|
const template = init?.quasi;
|
|
7934
|
-
const frames = parseKeyframesTemplate({
|
|
8006
|
+
const frames = parseKeyframesTemplate({
|
|
8007
|
+
template,
|
|
8008
|
+
j,
|
|
8009
|
+
scopePath: p
|
|
8010
|
+
});
|
|
7935
8011
|
if (!frames) return;
|
|
7936
8012
|
p.node.init = j.callExpression(j.memberExpression(j.identifier("stylex"), j.identifier("keyframes")), [objectToAst(j, frames)]);
|
|
7937
8013
|
keyframesNames.add(localName);
|
|
@@ -7996,7 +8072,7 @@ function extractInlineKeyframes(rules) {
|
|
|
7996
8072
|
* Expands static CSS declarations into a style object via cssDeclarationToStylexDeclarations.
|
|
7997
8073
|
* Handles shorthand expansion and coerces numeric strings to numbers.
|
|
7998
8074
|
*/
|
|
7999
|
-
function applyStaticDeclsToStyleObj(styleObj, property, valueRaw) {
|
|
8075
|
+
function applyStaticDeclsToStyleObj(styleObj, property, valueRaw, options) {
|
|
8000
8076
|
for (const out of cssDeclarationToStylexDeclarations({
|
|
8001
8077
|
property,
|
|
8002
8078
|
value: {
|
|
@@ -8007,9 +8083,91 @@ function applyStaticDeclsToStyleObj(styleObj, property, valueRaw) {
|
|
|
8007
8083
|
valueRaw
|
|
8008
8084
|
})) if (out.value.kind === "static") {
|
|
8009
8085
|
const v = out.value.value.trim();
|
|
8086
|
+
const exprValue = resolvePlaceholderValueToAst(v, options);
|
|
8087
|
+
if (exprValue) {
|
|
8088
|
+
styleObj[out.prop] = exprValue;
|
|
8089
|
+
continue;
|
|
8090
|
+
}
|
|
8010
8091
|
styleObj[out.prop] = /^-?\d*\.?\d+$/.test(v) ? Number(v) : v;
|
|
8011
8092
|
}
|
|
8012
8093
|
}
|
|
8094
|
+
function resolvePlaceholderValueToAst(value, options) {
|
|
8095
|
+
const j = options?.j;
|
|
8096
|
+
const slotExprById = options?.slotExprById;
|
|
8097
|
+
if (!j || !slotExprById || !/__SC_EXPR_\d+__/.test(value)) return null;
|
|
8098
|
+
const placeholderRe = /__SC_EXPR_(\d+)__/g;
|
|
8099
|
+
const quasis = [];
|
|
8100
|
+
const exprs = [];
|
|
8101
|
+
let lastIndex = 0;
|
|
8102
|
+
let match;
|
|
8103
|
+
while (match = placeholderRe.exec(value)) {
|
|
8104
|
+
const expr = slotExprById.get(Number(match[1]));
|
|
8105
|
+
if (!expr) return null;
|
|
8106
|
+
const prefix = value.slice(lastIndex, match.index);
|
|
8107
|
+
quasis.push(j.templateElement({
|
|
8108
|
+
raw: prefix,
|
|
8109
|
+
cooked: prefix
|
|
8110
|
+
}, false));
|
|
8111
|
+
exprs.push(cloneAstNode(expr));
|
|
8112
|
+
lastIndex = match.index + match[0].length;
|
|
8113
|
+
}
|
|
8114
|
+
if (exprs.length === 0) return null;
|
|
8115
|
+
const suffix = value.slice(lastIndex);
|
|
8116
|
+
quasis.push(j.templateElement({
|
|
8117
|
+
raw: suffix,
|
|
8118
|
+
cooked: suffix
|
|
8119
|
+
}, true));
|
|
8120
|
+
if (quasis.length === 2 && quasis[0].value.raw === "" && quasis[1].value.raw === "") return exprs[0];
|
|
8121
|
+
return j.templateLiteral(quasis, exprs);
|
|
8122
|
+
}
|
|
8123
|
+
function isStaticSafeKeyframesSlotExpression(expr, scopePath, seenIdentifiers = /* @__PURE__ */ new Set()) {
|
|
8124
|
+
if (isFunctionLikeExpression(expr)) return false;
|
|
8125
|
+
const staticValue = literalToStaticValue(expr);
|
|
8126
|
+
if (staticValue !== null) return typeof staticValue === "string" || typeof staticValue === "number";
|
|
8127
|
+
if (expr.type === "Identifier") return isStaticSafeIdentifierBinding(expr.name, scopePath, seenIdentifiers);
|
|
8128
|
+
if (expr.type === "UnaryExpression") return isStaticSafeKeyframesSlotExpression(expr.argument, scopePath, seenIdentifiers);
|
|
8129
|
+
if (expr.type === "BinaryExpression" || expr.type === "LogicalExpression") return isStaticSafeKeyframesSlotExpression(expr.left, scopePath, seenIdentifiers) && isStaticSafeKeyframesSlotExpression(expr.right, scopePath, seenIdentifiers);
|
|
8130
|
+
if (expr.type === "ConditionalExpression") return isStaticSafeKeyframesSlotExpression(expr.test, scopePath, seenIdentifiers) && isStaticSafeKeyframesSlotExpression(expr.consequent, scopePath, seenIdentifiers) && isStaticSafeKeyframesSlotExpression(expr.alternate, scopePath, seenIdentifiers);
|
|
8131
|
+
if (expr.type === "TemplateLiteral") return expr.expressions.every((slotExpr) => isStaticSafeKeyframesSlotExpression(slotExpr, scopePath, seenIdentifiers));
|
|
8132
|
+
if (expr.type === "ParenthesizedExpression") return isStaticSafeKeyframesSlotExpression(expr.expression, scopePath, seenIdentifiers);
|
|
8133
|
+
if (expr.type === "TSAsExpression" || expr.type === "TSTypeAssertion" || expr.type === "TSSatisfiesExpression") return isStaticSafeKeyframesSlotExpression(expr.expression, scopePath, seenIdentifiers);
|
|
8134
|
+
return false;
|
|
8135
|
+
}
|
|
8136
|
+
function isFunctionLikeExpression(expr) {
|
|
8137
|
+
return expr.type === "ArrowFunctionExpression" || expr.type === "FunctionExpression";
|
|
8138
|
+
}
|
|
8139
|
+
function isStaticSafeIdentifierBinding(name, scopePath, seenIdentifiers) {
|
|
8140
|
+
if (seenIdentifiers.has(name)) return false;
|
|
8141
|
+
seenIdentifiers.add(name);
|
|
8142
|
+
const scope = scopePath.scope?.lookup?.(name);
|
|
8143
|
+
if (!scope || typeof scope.getBindings !== "function") {
|
|
8144
|
+
seenIdentifiers.delete(name);
|
|
8145
|
+
return false;
|
|
8146
|
+
}
|
|
8147
|
+
const refs = scope.getBindings()?.[name];
|
|
8148
|
+
if (!Array.isArray(refs) || refs.length !== 1) {
|
|
8149
|
+
seenIdentifiers.delete(name);
|
|
8150
|
+
return false;
|
|
8151
|
+
}
|
|
8152
|
+
const idPath = refs[0];
|
|
8153
|
+
const declarator = idPath?.parent?.value;
|
|
8154
|
+
if (!declarator || declarator.type !== "VariableDeclarator" || declarator.id !== idPath.value) {
|
|
8155
|
+
seenIdentifiers.delete(name);
|
|
8156
|
+
return false;
|
|
8157
|
+
}
|
|
8158
|
+
const declaration = idPath?.parent?.parent?.value;
|
|
8159
|
+
if (!declaration || declaration.type !== "VariableDeclaration" || declaration.kind !== "const") {
|
|
8160
|
+
seenIdentifiers.delete(name);
|
|
8161
|
+
return false;
|
|
8162
|
+
}
|
|
8163
|
+
if (!declarator.init) {
|
|
8164
|
+
seenIdentifiers.delete(name);
|
|
8165
|
+
return false;
|
|
8166
|
+
}
|
|
8167
|
+
const isStatic = isStaticSafeKeyframesSlotExpression(declarator.init, scopePath, seenIdentifiers);
|
|
8168
|
+
seenIdentifiers.delete(name);
|
|
8169
|
+
return isStatic;
|
|
8170
|
+
}
|
|
8013
8171
|
/**
|
|
8014
8172
|
* Expands a static `animation` shorthand value into longhand properties,
|
|
8015
8173
|
* replacing the animation name with a keyframes identifier when it matches
|
|
@@ -10031,14 +10189,37 @@ function emitStylesStep(ctx) {
|
|
|
10031
10189
|
function emitDefineMarkerDeclarations(ctx, crossFileMarkers) {
|
|
10032
10190
|
const j = ctx.j;
|
|
10033
10191
|
const markerNames = [...crossFileMarkers.values()];
|
|
10034
|
-
ctx.sidecarStylexContent = `import * as stylex from "@stylexjs/stylex";\n\n${markerNames.map((name) =>
|
|
10035
|
-
|
|
10192
|
+
ctx.sidecarStylexContent = `import * as stylex from "@stylexjs/stylex";\n\n${markerNames.map((name) => {
|
|
10193
|
+
return `/** Custom marker for ${name.replace(/Marker$/, "")} */\nexport const ${name} = stylex.defineMarker();`;
|
|
10194
|
+
}).join("\n\n")}\n`;
|
|
10195
|
+
let sidecarImportPath;
|
|
10196
|
+
const adapterMarkerFile = ctx.adapter.markerFile;
|
|
10197
|
+
if (adapterMarkerFile) {
|
|
10198
|
+
const importSource = adapterMarkerFile({ filePath: ctx.file.path });
|
|
10199
|
+
sidecarImportPath = importSourceToModuleSpecifier(importSource, ctx.file.path);
|
|
10200
|
+
ctx.sidecarFilePath = importSourceToAbsolutePath(importSource, ctx.file.path);
|
|
10201
|
+
} else sidecarImportPath = `./${basename(ctx.file.path).replace(/\.\w+$/, "")}.stylex`;
|
|
10036
10202
|
const importDecl = j.importDeclaration(markerNames.map((name) => j.importSpecifier(j.identifier(name))), j.literal(sidecarImportPath));
|
|
10037
10203
|
const programBody = ctx.root.get().node.program.body;
|
|
10038
10204
|
const lastImportIdx = programBody.reduce((last, node, i) => node?.type === "ImportDeclaration" ? i : last, -1);
|
|
10039
10205
|
const insertAt = lastImportIdx >= 0 ? lastImportIdx + 1 : 0;
|
|
10040
10206
|
programBody.splice(insertAt, 0, importDecl);
|
|
10041
10207
|
}
|
|
10208
|
+
/** Convert an ImportSource to a module specifier string for use in import declarations. */
|
|
10209
|
+
function importSourceToModuleSpecifier(source, filePath) {
|
|
10210
|
+
if (source.kind === "specifier") return source.value;
|
|
10211
|
+
let rel = relative(dirname(filePath), source.value).split(sep).join("/");
|
|
10212
|
+
rel = rel.replace(/\.tsx?$/, "");
|
|
10213
|
+
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
10214
|
+
return rel;
|
|
10215
|
+
}
|
|
10216
|
+
/** Resolve an ImportSource to an absolute file path for writing the sidecar file. */
|
|
10217
|
+
function importSourceToAbsolutePath(source, filePath) {
|
|
10218
|
+
if (source.kind === "absolutePath") return source.value;
|
|
10219
|
+
let resolved = join(dirname(filePath), source.value);
|
|
10220
|
+
if (!/\.[jt]sx?$/.test(resolved)) resolved += ".ts";
|
|
10221
|
+
return resolved;
|
|
10222
|
+
}
|
|
10042
10223
|
//#endregion
|
|
10043
10224
|
//#region src/internal/transform-steps/emit-bridge-exports.ts
|
|
10044
10225
|
/**
|
|
@@ -14960,6 +15141,7 @@ function finalize(ctx) {
|
|
|
14960
15141
|
code,
|
|
14961
15142
|
warnings: ctx.warnings,
|
|
14962
15143
|
sidecarContent: ctx.sidecarStylexContent,
|
|
15144
|
+
sidecarFilePath: ctx.sidecarFilePath,
|
|
14963
15145
|
bridgeResults: ctx.bridgeResults,
|
|
14964
15146
|
transientPropRenames: ctx.transientPropRenames
|
|
14965
15147
|
};
|
|
@@ -15940,6 +16122,15 @@ function createCssHelperResolver(args) {
|
|
|
15940
16122
|
}
|
|
15941
16123
|
return null;
|
|
15942
16124
|
};
|
|
16125
|
+
/**
|
|
16126
|
+
* Extracts the theme path from a ternary test that accesses `props.theme.*`.
|
|
16127
|
+
* e.g., `props.theme.isDark` → "isDark", `props.theme.mode` → "mode"
|
|
16128
|
+
*/
|
|
16129
|
+
const extractThemePathFromCondTest = (test, paramName) => {
|
|
16130
|
+
if (!test || !paramName) return null;
|
|
16131
|
+
const path = getMemberPathFromIdentifier(test, paramName);
|
|
16132
|
+
return path && path[0] === "theme" && path.length > 1 ? path.slice(1).join(".") : null;
|
|
16133
|
+
};
|
|
15943
16134
|
const resolveCssHelperTemplate = (template, paramName, loc) => {
|
|
15944
16135
|
const bail = (type, context, exprLoc) => {
|
|
15945
16136
|
warnings.push({
|
|
@@ -16078,6 +16269,38 @@ function createCssHelperResolver(args) {
|
|
|
16078
16269
|
return bail("Conditional `css` block: failed to parse expression", { property: d.property }, exprLoc);
|
|
16079
16270
|
}
|
|
16080
16271
|
const resolved = resolveHelperExprToAst(expr, paramName);
|
|
16272
|
+
if (!resolved && expr.type === "ConditionalExpression") {
|
|
16273
|
+
const ternaryExpr = expr;
|
|
16274
|
+
const themePath = extractThemePathFromCondTest(ternaryExpr.test, paramName);
|
|
16275
|
+
if (themePath) {
|
|
16276
|
+
const consResolved = resolveTernaryBranchToAst(ternaryExpr.consequent);
|
|
16277
|
+
const altResolved = resolveTernaryBranchToAst(ternaryExpr.alternate);
|
|
16278
|
+
if (consResolved && altResolved) {
|
|
16279
|
+
const buildVariantStyle = (branchResolved) => {
|
|
16280
|
+
const variantStyle = {};
|
|
16281
|
+
for (const mapped of cssDeclarationToStylexDeclarations(d)) if (hasStaticParts) {
|
|
16282
|
+
const { prefix, suffix } = extractPrefixSuffix(parts);
|
|
16283
|
+
const ast = parseExpr(wrapExprWithStaticParts(branchResolved.exprString, prefix, suffix));
|
|
16284
|
+
if (ast) variantStyle[mapped.prop] = mergeIntoContext(ast, mapped.prop, target);
|
|
16285
|
+
} else variantStyle[mapped.prop] = mergeIntoContext(branchResolved.ast, mapped.prop, target);
|
|
16286
|
+
return variantStyle;
|
|
16287
|
+
};
|
|
16288
|
+
const consStyle = buildVariantStyle(consResolved);
|
|
16289
|
+
const altStyle = buildVariantStyle(altResolved);
|
|
16290
|
+
conditionalVariants.push({
|
|
16291
|
+
when: `theme.${themePath}`,
|
|
16292
|
+
propName: "",
|
|
16293
|
+
style: consStyle
|
|
16294
|
+
});
|
|
16295
|
+
conditionalVariants.push({
|
|
16296
|
+
when: `!theme.${themePath}`,
|
|
16297
|
+
propName: "",
|
|
16298
|
+
style: altStyle
|
|
16299
|
+
});
|
|
16300
|
+
continue;
|
|
16301
|
+
}
|
|
16302
|
+
}
|
|
16303
|
+
}
|
|
16081
16304
|
if (!resolved && hasThemeAccessInExpr(expr, paramName)) return bail("Conditional `css` block: failed to parse expression", { property: d.property }, exprLoc);
|
|
16082
16305
|
if (resolved) if (hasStaticParts) {
|
|
16083
16306
|
const { prefix, suffix } = extractPrefixSuffix(parts);
|
|
@@ -19767,6 +19990,24 @@ function createCssHelperConditionalHandler(ctx) {
|
|
|
19767
19990
|
};
|
|
19768
19991
|
return replace(cloned, void 0);
|
|
19769
19992
|
};
|
|
19993
|
+
/** Apply conditional variants, composing with an outer condition, and inject useTheme() for theme refs. */
|
|
19994
|
+
const applyConditionalVariantsInline = (conditionalVariants, outerCondition) => {
|
|
19995
|
+
for (const cv of conditionalVariants) {
|
|
19996
|
+
applyVariant({
|
|
19997
|
+
when: `${outerCondition} && ${cv.when}`,
|
|
19998
|
+
propName: cv.propName
|
|
19999
|
+
}, cv.style);
|
|
20000
|
+
if (cv.propName) ensureShouldForwardPropDrop(decl, cv.propName);
|
|
20001
|
+
if (cv.when.startsWith("theme.") || cv.when.startsWith("!theme.")) {
|
|
20002
|
+
if (!decl.needsUseThemeHook) decl.needsUseThemeHook = [];
|
|
20003
|
+
if (!decl.needsUseThemeHook.some((e) => e.trueStyleKey === null && e.falseStyleKey === null)) decl.needsUseThemeHook.push({
|
|
20004
|
+
themeProp: "__variantCondition",
|
|
20005
|
+
trueStyleKey: null,
|
|
20006
|
+
falseStyleKey: null
|
|
20007
|
+
});
|
|
20008
|
+
}
|
|
20009
|
+
}
|
|
20010
|
+
};
|
|
19770
20011
|
const resolveCssBranchToInlineMap = (node) => {
|
|
19771
20012
|
let tpl = null;
|
|
19772
20013
|
if (isCssHelperTaggedTemplate(node)) tpl = node.quasi;
|
|
@@ -19911,13 +20152,8 @@ function createCssHelperConditionalHandler(ctx) {
|
|
|
19911
20152
|
}
|
|
19912
20153
|
}
|
|
19913
20154
|
if (Object.keys(consStyle).length > 0) applyVariant(testInfo, consStyle);
|
|
19914
|
-
|
|
19915
|
-
|
|
19916
|
-
when: `${testInfo.when} && ${cv.when}`,
|
|
19917
|
-
propName: cv.propName
|
|
19918
|
-
}, cv.style);
|
|
19919
|
-
ensureShouldForwardPropDrop(decl, cv.propName);
|
|
19920
|
-
}
|
|
20155
|
+
applyConditionalVariantsInline(conditionalVariants, testInfo.when);
|
|
20156
|
+
dropAllTestInfoProps(testInfo);
|
|
19921
20157
|
return true;
|
|
19922
20158
|
}
|
|
19923
20159
|
if (body.right?.type === "StringLiteral" || body.right?.type === "Literal" && typeof body.right.value === "string") {
|
|
@@ -20374,15 +20610,7 @@ function createCssHelperConditionalHandler(ctx) {
|
|
|
20374
20610
|
if (!isCssHelperTaggedTemplate(node)) return null;
|
|
20375
20611
|
return resolveCssHelperTemplate(node.quasi, paramName, decl.loc);
|
|
20376
20612
|
};
|
|
20377
|
-
const applyConditionalVariants =
|
|
20378
|
-
for (const cv of conditionalVariants) {
|
|
20379
|
-
applyVariant({
|
|
20380
|
-
when: `${outerCondition} && ${cv.when}`,
|
|
20381
|
-
propName: cv.propName
|
|
20382
|
-
}, cv.style);
|
|
20383
|
-
ensureShouldForwardPropDrop(decl, cv.propName);
|
|
20384
|
-
}
|
|
20385
|
-
};
|
|
20613
|
+
const applyConditionalVariants = applyConditionalVariantsInline;
|
|
20386
20614
|
if (consIsCss && altIsCss) {
|
|
20387
20615
|
const consResolved = resolveCssBranch(cons);
|
|
20388
20616
|
const altResolved = resolveCssBranch(alt);
|
|
@@ -27810,7 +28038,13 @@ function preflight(ctx) {
|
|
|
27810
28038
|
const styledLocalNames = /* @__PURE__ */ new Set();
|
|
27811
28039
|
styledImports.forEach((imp) => {
|
|
27812
28040
|
const specs = imp.node.specifiers ?? [];
|
|
27813
|
-
for (const spec of specs)
|
|
28041
|
+
for (const spec of specs) {
|
|
28042
|
+
if (spec.type === "ImportDefaultSpecifier" && spec.local?.type === "Identifier") {
|
|
28043
|
+
styledLocalNames.add(spec.local.name);
|
|
28044
|
+
continue;
|
|
28045
|
+
}
|
|
28046
|
+
if (spec.type === "ImportSpecifier" && spec.imported?.type === "Identifier" && spec.imported.name === "styled" && spec.local?.type === "Identifier") styledLocalNames.add(spec.local.name);
|
|
28047
|
+
}
|
|
27814
28048
|
});
|
|
27815
28049
|
ctx.styledLocalNames = styledLocalNames;
|
|
27816
28050
|
ctx.isStyledTag = (tag) => isStyledTag(styledLocalNames, tag);
|
|
@@ -28449,9 +28683,9 @@ function transform(file, api, options) {
|
|
|
28449
28683
|
if (result.sidecarContent) {
|
|
28450
28684
|
const sidecarFiles = options.sidecarFiles;
|
|
28451
28685
|
if (sidecarFiles) {
|
|
28452
|
-
const
|
|
28453
|
-
const
|
|
28454
|
-
sidecarFiles.set(
|
|
28686
|
+
const sidecarPath = result.sidecarFilePath ?? join(dirname(file.path), `${basename(file.path).replace(/\.\w+$/, "")}.stylex.ts`);
|
|
28687
|
+
const existing = sidecarFiles.get(sidecarPath);
|
|
28688
|
+
sidecarFiles.set(sidecarPath, existing ? mergeMarkerDeclarations(existing, result.sidecarContent) : result.sidecarContent);
|
|
28455
28689
|
}
|
|
28456
28690
|
}
|
|
28457
28691
|
if (result.bridgeResults && result.bridgeResults.length > 0) {
|