@remotion/studio-server 4.0.526 → 4.0.528
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/codemods/apply-codemod-to-file.d.ts +2 -1
- package/dist/codemods/apply-codemod-to-file.js +142 -8
- package/dist/codemods/{delete-jsx-node.d.ts → delete-jsx-nodes.d.ts} +1 -10
- package/dist/codemods/delete-jsx-nodes.js +10 -0
- package/dist/codemods/paste-effects.d.ts +15 -1
- package/dist/codemods/paste-effects.js +3 -2
- package/dist/codemods/split-jsx-sequence.d.ts +14 -0
- package/dist/codemods/split-jsx-sequence.js +10 -3
- package/dist/codemods/update-effect-props/update-effect-props.d.ts +11 -3
- package/dist/codemods/update-effect-props/update-effect-props.js +17 -10
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +31 -10
- package/dist/codemods/update-keyframes/update-keyframes.js +24 -7
- package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +3 -6
- package/dist/codemods/update-sequence-props/update-sequence-props.js +16 -9
- package/dist/helpers/open-file-for-writing-without-symlinks.d.ts +6 -1
- package/dist/helpers/open-file-for-writing-without-symlinks.js +9 -6
- package/dist/helpers/resolve-composition-component.d.ts +1 -1
- package/dist/helpers/resolve-composition-component.js +5 -4
- package/dist/index.d.ts +0 -19
- package/dist/index.js +0 -6
- package/dist/preview-server/api-routes.js +8 -2
- package/dist/preview-server/hot-middleware/index.js +13 -46
- package/dist/preview-server/routes/add-effect.js +17 -8
- package/dist/preview-server/routes/apply-codemod.d.ts +0 -19
- package/dist/preview-server/routes/apply-codemod.js +24 -26
- package/dist/preview-server/routes/apply-visual-control-change.js +13 -65
- package/dist/preview-server/routes/can-update-default-props.d.ts +1 -1
- package/dist/preview-server/routes/can-update-default-props.js +3 -4
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +0 -10
- package/dist/preview-server/routes/can-update-sequence-props.js +62 -495
- package/dist/preview-server/routes/delete-effect.js +15 -13
- package/dist/preview-server/routes/delete-jsx-nodes.d.ts +3 -0
- package/dist/preview-server/routes/{delete-jsx-node.js → delete-jsx-nodes.js} +23 -12
- package/dist/preview-server/routes/download-remote-asset.d.ts +5 -0
- package/dist/preview-server/routes/download-remote-asset.js +25 -20
- package/dist/preview-server/routes/duplicate-effect.js +12 -4
- package/dist/preview-server/routes/duplicate-jsx-node.js +15 -4
- package/dist/preview-server/routes/element-install-plan.d.ts +1 -1
- package/dist/preview-server/routes/find-in-file.d.ts +9 -1
- package/dist/preview-server/routes/find-in-file.js +3 -4
- package/dist/preview-server/routes/insert-basic-captions.d.ts +3 -0
- package/dist/preview-server/routes/insert-basic-captions.js +119 -0
- package/dist/preview-server/routes/insert-element.js +399 -280
- package/dist/preview-server/routes/install-dependency.js +14 -4
- package/dist/preview-server/routes/prepare-element-install.js +3 -0
- package/dist/preview-server/routes/reorder-effect.js +12 -5
- package/dist/preview-server/routes/reorder-sequence.js +10 -5
- package/dist/preview-server/routes/replace-video-source.d.ts +3 -0
- package/dist/preview-server/routes/replace-video-source.js +81 -0
- package/dist/preview-server/routes/save-sequence-props.js +8 -28
- package/dist/preview-server/routes/split-jsx-sequence.js +82 -42
- package/dist/preview-server/routes/split-video-from-audio.js +9 -4
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +6 -10
- package/dist/preview-server/routes/update-config.js +38 -2
- package/dist/preview-server/routes/update-default-props.js +12 -8
- package/dist/preview-server/routes/wrap-jsx-node.d.ts +3 -0
- package/dist/preview-server/routes/wrap-jsx-node.js +97 -0
- package/dist/preview-server/studio-protocol/handle-discovery.js +1 -1
- package/dist/preview-server/studio-protocol/handle-element-library.js +3 -3
- package/dist/preview-server/undo-stack.d.ts +2 -1
- package/dist/preview-server/undo-stack.js +19 -0
- package/dist/routes.js +2 -0
- package/package.json +8 -8
- package/dist/canvas-capture/generate-canvas-capture-composition.d.ts +0 -14
- package/dist/canvas-capture/generate-canvas-capture-composition.js +0 -239
- package/dist/codemods/add-effect.d.ts +0 -1
- package/dist/codemods/add-effect.js +0 -8
- package/dist/codemods/apply-visual-control.d.ts +0 -8
- package/dist/codemods/apply-visual-control.js +0 -89
- package/dist/codemods/delete-effect.d.ts +0 -1
- package/dist/codemods/delete-effect.js +0 -6
- package/dist/codemods/delete-jsx-node.js +0 -17
- package/dist/codemods/duplicate-composition.d.ts +0 -2
- package/dist/codemods/duplicate-composition.js +0 -64
- package/dist/codemods/duplicate-effect.d.ts +0 -1
- package/dist/codemods/duplicate-effect.js +0 -6
- package/dist/codemods/duplicate-jsx-node.d.ts +0 -25
- package/dist/codemods/duplicate-jsx-node.js +0 -26
- package/dist/codemods/format-file-content.d.ts +0 -7
- package/dist/codemods/format-file-content.js +0 -80
- package/dist/codemods/format-inline-content.d.ts +0 -18
- package/dist/codemods/format-inline-content.js +0 -78
- package/dist/codemods/recast-mods.d.ts +0 -13
- package/dist/codemods/recast-mods.js +0 -902
- package/dist/codemods/reorder-effect.d.ts +0 -1
- package/dist/codemods/reorder-effect.js +0 -5
- package/dist/codemods/reorder-sequence.d.ts +0 -1
- package/dist/codemods/reorder-sequence.js +0 -5
- package/dist/codemods/simple-diff.d.ts +0 -5
- package/dist/codemods/simple-diff.js +0 -39
- package/dist/codemods/split-video-from-audio.d.ts +0 -1
- package/dist/codemods/split-video-from-audio.js +0 -5
- package/dist/codemods/update-default-props.d.ts +0 -1
- package/dist/codemods/update-default-props.js +0 -6
- package/dist/codemods/update-inline-caption-patches.d.ts +0 -1
- package/dist/codemods/update-inline-caption-patches.js +0 -5
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +0 -1
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +0 -7
- package/dist/preview-server/routes/delete-jsx-node.d.ts +0 -3
- package/dist/preview-server/routes/update-public-license.d.ts +0 -11
- package/dist/preview-server/routes/update-public-license.js +0 -97
|
@@ -33,68 +33,20 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.computeSequencePropsStatusFromFilenameByLocation = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.
|
|
36
|
+
exports.computeSequencePropsStatusFromFilenameByLocation = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.resolveSequencePropsNodePathsFromFilename = exports.lineColumnsToNodePaths = exports.lineColumnToNodePath = exports.findNodePathForJsxElement = exports.getStaticJsxTextContent = exports.hasJsxChildrenAttribute = exports.getStaticJsxChildrenAttribute = exports.findJsxElementNodeAtNodePath = exports.findJsxElementAtNodePath = exports.findJsxElementPathAtNodePath = exports.getNodePathForRecastPath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
|
+
const codemods_1 = require("@remotion/codemods");
|
|
38
39
|
const renderer_1 = require("@remotion/renderer");
|
|
39
40
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
40
41
|
const recast = __importStar(require("recast"));
|
|
41
42
|
const no_react_1 = require("remotion/no-react");
|
|
42
|
-
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
43
|
-
const css_shorthand_properties_1 = require("../../helpers/css-shorthand-properties");
|
|
44
43
|
const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
|
|
45
44
|
const import_agnostic_node_path_1 = require("../../helpers/import-agnostic-node-path");
|
|
46
|
-
const parse_border_radius_shorthand_1 = require("../../helpers/parse-border-radius-shorthand");
|
|
47
45
|
const parse_keyframe_easing_expression_1 = require("../../helpers/parse-keyframe-easing-expression");
|
|
48
46
|
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
49
47
|
const video_config_numeric_expression_1 = require("../../helpers/video-config-numeric-expression");
|
|
50
|
-
const video_config_values_1 = require("../../helpers/video-config-values");
|
|
51
48
|
const jsx_component_identity_1 = require("../jsx-component-identity");
|
|
52
49
|
const jsx_element_not_found_at_location_error_1 = require("../jsx-element-not-found-at-location-error");
|
|
53
|
-
const can_update_effect_props_1 = require("./can-update-effect-props");
|
|
54
|
-
// A file write synchronously notifies every sequence subscription. Status
|
|
55
|
-
// computation is read-only, so all subscribers can share one parsed snapshot
|
|
56
|
-
// until the notification burst has finished.
|
|
57
|
-
let cachedSequencePropsStatusAst = null;
|
|
58
|
-
// A subsequent save can consume the last read-only snapshot if the file has
|
|
59
|
-
// not changed. The save mutates the AST, so it must only be reused once.
|
|
60
|
-
let reusableSequencePropsStatusAst = null;
|
|
61
|
-
const getCachedSequencePropsStatusAst = (fileContents) => {
|
|
62
|
-
if ((cachedSequencePropsStatusAst === null || cachedSequencePropsStatusAst === void 0 ? void 0 : cachedSequencePropsStatusAst.fileContents) !== fileContents) {
|
|
63
|
-
const snapshot = {
|
|
64
|
-
fileContents,
|
|
65
|
-
ast: (0, parse_ast_1.parseAst)(fileContents),
|
|
66
|
-
videoConfigIdentifierValues: new Map(),
|
|
67
|
-
};
|
|
68
|
-
cachedSequencePropsStatusAst = snapshot;
|
|
69
|
-
reusableSequencePropsStatusAst = snapshot;
|
|
70
|
-
queueMicrotask(() => {
|
|
71
|
-
if (cachedSequencePropsStatusAst === snapshot) {
|
|
72
|
-
cachedSequencePropsStatusAst = null;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
return cachedSequencePropsStatusAst;
|
|
77
|
-
};
|
|
78
|
-
const takeCachedSequencePropsStatusAst = (fileContents) => {
|
|
79
|
-
if ((reusableSequencePropsStatusAst === null || reusableSequencePropsStatusAst === void 0 ? void 0 : reusableSequencePropsStatusAst.fileContents) !== fileContents) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
const { ast } = reusableSequencePropsStatusAst;
|
|
83
|
-
reusableSequencePropsStatusAst = null;
|
|
84
|
-
if ((cachedSequencePropsStatusAst === null || cachedSequencePropsStatusAst === void 0 ? void 0 : cachedSequencePropsStatusAst.ast) === ast) {
|
|
85
|
-
cachedSequencePropsStatusAst = null;
|
|
86
|
-
}
|
|
87
|
-
return ast;
|
|
88
|
-
};
|
|
89
|
-
exports.takeCachedSequencePropsStatusAst = takeCachedSequencePropsStatusAst;
|
|
90
|
-
const staticStatus = (codeValue, numericExpression) => ({
|
|
91
|
-
status: 'static',
|
|
92
|
-
keyframeDisplayOffsetAdjustment: null,
|
|
93
|
-
codeValue,
|
|
94
|
-
...(numericExpression === null || numericExpression.type === 'literal'
|
|
95
|
-
? {}
|
|
96
|
-
: { numericExpression }),
|
|
97
|
-
});
|
|
98
50
|
const computedStatus = () => ({
|
|
99
51
|
status: 'computed',
|
|
100
52
|
});
|
|
@@ -257,6 +209,22 @@ const getInterpolateOutputOption = (node) => {
|
|
|
257
209
|
}
|
|
258
210
|
return null;
|
|
259
211
|
};
|
|
212
|
+
const getInterpolateOutputType = (node) => {
|
|
213
|
+
if (node.type === 'StringLiteral') {
|
|
214
|
+
if (node.value === 'font-weight' ||
|
|
215
|
+
node.value === 'scale' ||
|
|
216
|
+
node.value === 'translate' ||
|
|
217
|
+
node.value === 'rotate' ||
|
|
218
|
+
node.value === 'transform-origin') {
|
|
219
|
+
return node.value;
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
if (node.type === 'TSAsExpression') {
|
|
224
|
+
return getInterpolateOutputType(node.expression);
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
};
|
|
260
228
|
const getKeyframeEasing = (node) => (0, parse_keyframe_easing_expression_1.parseKeyframeEasingExpression)(node);
|
|
261
229
|
const getKeyframeEasingArray = ({ easingNode, segments, }) => {
|
|
262
230
|
if (segments === 0) {
|
|
@@ -376,6 +344,13 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
|
|
|
376
344
|
output = parsedOutput;
|
|
377
345
|
continue;
|
|
378
346
|
}
|
|
347
|
+
if (key === 'outputType') {
|
|
348
|
+
if (interpolationFunction === 'interpolateColors' ||
|
|
349
|
+
getInterpolateOutputType(value) === null) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
379
354
|
return null;
|
|
380
355
|
}
|
|
381
356
|
return {
|
|
@@ -603,28 +578,6 @@ const getFrameDisplayOffsetAdjustmentBetweenPaths = ({ startPath, endPath, video
|
|
|
603
578
|
}
|
|
604
579
|
return current ? { adjustment, hasEnclosingElement } : null;
|
|
605
580
|
};
|
|
606
|
-
const getDefaultFrameDisplayOffsetAdjustment = ({ jsxPath, videoConfigValues, }) => {
|
|
607
|
-
var _a;
|
|
608
|
-
let functionPath = jsxPath.parentPath;
|
|
609
|
-
while (functionPath) {
|
|
610
|
-
const node = functionPath.value;
|
|
611
|
-
if (node.type === 'FunctionDeclaration' ||
|
|
612
|
-
node.type === 'FunctionExpression' ||
|
|
613
|
-
node.type === 'ArrowFunctionExpression') {
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
functionPath = functionPath.parentPath;
|
|
617
|
-
}
|
|
618
|
-
if (!functionPath) {
|
|
619
|
-
return null;
|
|
620
|
-
}
|
|
621
|
-
const result = getFrameDisplayOffsetAdjustmentBetweenPaths({
|
|
622
|
-
startPath: jsxPath,
|
|
623
|
-
endPath: functionPath,
|
|
624
|
-
videoConfigValues,
|
|
625
|
-
});
|
|
626
|
-
return (_a = result === null || result === void 0 ? void 0 : result.adjustment) !== null && _a !== void 0 ? _a : null;
|
|
627
|
-
};
|
|
628
581
|
const resolveCurrentFrameExpression = ({ node, ast, seenDeclarations, }) => {
|
|
629
582
|
var _a;
|
|
630
583
|
if (node.type === 'TSAsExpression') {
|
|
@@ -771,58 +724,6 @@ const getComputedStatus = (node, ast, videoConfigValues) => {
|
|
|
771
724
|
};
|
|
772
725
|
};
|
|
773
726
|
exports.getComputedStatus = getComputedStatus;
|
|
774
|
-
const getPropsStatus = (jsxElement, ast, videoConfigValues, assetKeys) => {
|
|
775
|
-
const props = {};
|
|
776
|
-
for (const attr of jsxElement.attributes) {
|
|
777
|
-
if (attr.type === 'JSXSpreadAttribute') {
|
|
778
|
-
// The spread may override every prop written before it
|
|
779
|
-
for (const key of Object.keys(props)) {
|
|
780
|
-
props[key] = computedStatus();
|
|
781
|
-
}
|
|
782
|
-
continue;
|
|
783
|
-
}
|
|
784
|
-
if (attr.name.type === 'JSXNamespacedName') {
|
|
785
|
-
continue;
|
|
786
|
-
}
|
|
787
|
-
const { name } = attr.name;
|
|
788
|
-
if (typeof name !== 'string') {
|
|
789
|
-
continue;
|
|
790
|
-
}
|
|
791
|
-
const { value } = attr;
|
|
792
|
-
if (!value) {
|
|
793
|
-
props[name] = staticStatus(true, null);
|
|
794
|
-
continue;
|
|
795
|
-
}
|
|
796
|
-
if (value.type === 'StringLiteral') {
|
|
797
|
-
props[name] = staticStatus(value.value, null);
|
|
798
|
-
continue;
|
|
799
|
-
}
|
|
800
|
-
if (value.type === 'JSXExpressionContainer') {
|
|
801
|
-
const { expression } = value;
|
|
802
|
-
const staticValueOptions = {
|
|
803
|
-
allowSpecialValues: assetKeys.includes(name),
|
|
804
|
-
};
|
|
805
|
-
if (expression.type === 'JSXEmptyExpression') {
|
|
806
|
-
props[name] = computedStatus();
|
|
807
|
-
continue;
|
|
808
|
-
}
|
|
809
|
-
if (!(0, exports.isStaticValue)(expression, staticValueOptions)) {
|
|
810
|
-
const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
|
|
811
|
-
node: expression,
|
|
812
|
-
videoConfigValues,
|
|
813
|
-
});
|
|
814
|
-
props[name] = numericExpression
|
|
815
|
-
? staticStatus(numericExpression.value, numericExpression)
|
|
816
|
-
: (0, exports.getComputedStatus)(expression, ast, videoConfigValues);
|
|
817
|
-
continue;
|
|
818
|
-
}
|
|
819
|
-
props[name] = staticStatus((0, exports.extractStaticValue)(expression, staticValueOptions), null);
|
|
820
|
-
continue;
|
|
821
|
-
}
|
|
822
|
-
props[name] = computedStatus();
|
|
823
|
-
}
|
|
824
|
-
return props;
|
|
825
|
-
};
|
|
826
727
|
const getNodePathForRecastPath = (
|
|
827
728
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
828
729
|
recastPath, ast) => {
|
|
@@ -1026,382 +927,46 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
|
|
|
1026
927
|
action: 'read',
|
|
1027
928
|
});
|
|
1028
929
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
exports.resolveSequencePropsNodePathsFromFilename = resolveSequencePropsNodePathsFromFilename;
|
|
1033
|
-
const PIXEL_VALUE_REGEX = /^-?\d+(\.\d+)?px$/;
|
|
1034
|
-
const isSupportedTranslateValue = (value) => {
|
|
1035
|
-
const parts = value.split(/\s+/);
|
|
1036
|
-
if (parts.length >= 1 && parts.length <= 3) {
|
|
1037
|
-
return parts.every((part) => PIXEL_VALUE_REGEX.test(part));
|
|
1038
|
-
}
|
|
1039
|
-
return false;
|
|
1040
|
-
};
|
|
1041
|
-
const validateStyleValue = (childKey, value) => {
|
|
1042
|
-
if (childKey === 'translate' && typeof value === 'string') {
|
|
1043
|
-
return isSupportedTranslateValue(value);
|
|
1044
|
-
}
|
|
1045
|
-
return true;
|
|
1046
|
-
};
|
|
1047
|
-
const getObjectPropertyName = (property) => {
|
|
1048
|
-
if (property.key.type === 'Identifier') {
|
|
1049
|
-
return property.key.name;
|
|
1050
|
-
}
|
|
1051
|
-
if (property.key.type === 'StringLiteral') {
|
|
1052
|
-
return property.key.value;
|
|
1053
|
-
}
|
|
1054
|
-
return null;
|
|
1055
|
-
};
|
|
1056
|
-
const BORDER_RADIUS_SHORTHAND = 'borderRadius';
|
|
1057
|
-
const BORDER_RADIUS_LONGHANDS = [
|
|
1058
|
-
'borderTopLeftRadius',
|
|
1059
|
-
'borderTopRightRadius',
|
|
1060
|
-
'borderBottomRightRadius',
|
|
1061
|
-
'borderBottomLeftRadius',
|
|
1062
|
-
];
|
|
1063
|
-
const BORDER_RADIUS_PROPERTIES = new Set([
|
|
1064
|
-
BORDER_RADIUS_SHORTHAND,
|
|
1065
|
-
...BORDER_RADIUS_LONGHANDS,
|
|
1066
|
-
]);
|
|
1067
|
-
const hasMixedBorderRadiusRepresentation = (jsxElement) => {
|
|
1068
|
-
var _a;
|
|
1069
|
-
const style = jsxElement.attributes.find((attribute) => attribute.type === 'JSXAttribute' &&
|
|
1070
|
-
attribute.name.type !== 'JSXNamespacedName' &&
|
|
1071
|
-
attribute.name.name === 'style');
|
|
1072
|
-
if (!style ||
|
|
1073
|
-
style.type !== 'JSXAttribute' ||
|
|
1074
|
-
((_a = style.value) === null || _a === void 0 ? void 0 : _a.type) !== 'JSXExpressionContainer' ||
|
|
1075
|
-
style.value.expression.type !== 'ObjectExpression') {
|
|
1076
|
-
return false;
|
|
1077
|
-
}
|
|
1078
|
-
let hasShorthand = false;
|
|
1079
|
-
let hasLonghand = false;
|
|
1080
|
-
for (const property of style.value.expression.properties) {
|
|
1081
|
-
if (property.type !== 'ObjectProperty') {
|
|
1082
|
-
continue;
|
|
1083
|
-
}
|
|
1084
|
-
const name = getObjectPropertyName(property);
|
|
1085
|
-
hasShorthand || (hasShorthand = name === BORDER_RADIUS_SHORTHAND);
|
|
1086
|
-
hasLonghand || (hasLonghand = BORDER_RADIUS_LONGHANDS.some((longhand) => longhand === name));
|
|
1087
|
-
}
|
|
1088
|
-
return hasShorthand && hasLonghand;
|
|
1089
|
-
};
|
|
1090
|
-
const getUniformBorderRadius = (value) => {
|
|
1091
|
-
const parsed = (0, parse_border_radius_shorthand_1.parseBorderRadiusShorthand)(value);
|
|
1092
|
-
if (!parsed) {
|
|
1093
|
-
return null;
|
|
1094
|
-
}
|
|
1095
|
-
const values = Object.values(parsed);
|
|
1096
|
-
return values.every((radius) => radius === values[0]) ? values[0] : null;
|
|
1097
|
-
};
|
|
1098
|
-
const getBorderRadiusShorthandStatus = ({ propValue, ast, videoConfigValues, }) => {
|
|
1099
|
-
if ((0, exports.isStaticValue)(propValue)) {
|
|
1100
|
-
const uniform = getUniformBorderRadius((0, exports.extractStaticValue)(propValue));
|
|
1101
|
-
return uniform === null ? computedStatus() : staticStatus(uniform, null);
|
|
1102
|
-
}
|
|
1103
|
-
const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
|
|
1104
|
-
node: propValue,
|
|
1105
|
-
videoConfigValues,
|
|
930
|
+
const nodes = (0, codemods_1.getJsxNodes)({
|
|
931
|
+
project: { rootDir: remotionRoot, files: { [absolutePath]: fileContents } },
|
|
932
|
+
filePath: absolutePath,
|
|
1106
933
|
});
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
computed.keyframes.every((keyframe) => typeof keyframe.value === 'number' &&
|
|
1114
|
-
Number.isFinite(keyframe.value) &&
|
|
1115
|
-
keyframe.value >= 0)) {
|
|
1116
|
-
return computed;
|
|
1117
|
-
}
|
|
1118
|
-
return computedStatus();
|
|
1119
|
-
};
|
|
1120
|
-
const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfigValues, allowSpecialValues, lastSpreadIndex, }) => {
|
|
1121
|
-
const attrIndex = jsxElement.attributes.findIndex((a) => a.type !== 'JSXSpreadAttribute' &&
|
|
1122
|
-
a.name.type !== 'JSXNamespacedName' &&
|
|
1123
|
-
a.name.name === parentKey);
|
|
1124
|
-
const attr = attrIndex === -1
|
|
1125
|
-
? undefined
|
|
1126
|
-
: jsxElement.attributes[attrIndex];
|
|
1127
|
-
if (attrIndex !== -1 && attrIndex < lastSpreadIndex) {
|
|
1128
|
-
// A later spread may replace the whole parent object
|
|
1129
|
-
return computedStatus();
|
|
1130
|
-
}
|
|
1131
|
-
if (!attr) {
|
|
1132
|
-
if (lastSpreadIndex !== -1) {
|
|
1133
|
-
// The spread may provide the parent object
|
|
1134
|
-
return computedStatus();
|
|
1135
|
-
}
|
|
1136
|
-
// Parent attribute doesn't exist, nested prop can be added
|
|
1137
|
-
return staticStatus(undefined, null);
|
|
1138
|
-
}
|
|
1139
|
-
if (!attr.value) {
|
|
1140
|
-
return staticStatus(undefined, null);
|
|
1141
|
-
}
|
|
1142
|
-
if (attr.value.type !== 'JSXExpressionContainer') {
|
|
1143
|
-
return computedStatus();
|
|
1144
|
-
}
|
|
1145
|
-
const { expression } = attr.value;
|
|
1146
|
-
if (expression.type === 'JSXEmptyExpression' ||
|
|
1147
|
-
expression.type !== 'ObjectExpression') {
|
|
1148
|
-
// Parent is not an object literal (e.g. style={myStyles})
|
|
1149
|
-
return computedStatus();
|
|
1150
|
-
}
|
|
1151
|
-
const objExpr = expression;
|
|
1152
|
-
const cssShorthand = (0, css_shorthand_properties_1.getCssShorthandForLonghand)({
|
|
1153
|
-
parentKey,
|
|
1154
|
-
longhand: childKey,
|
|
1155
|
-
});
|
|
1156
|
-
if (cssShorthand &&
|
|
1157
|
-
objExpr.properties.some((property) => {
|
|
1158
|
-
if (property.type !== 'ObjectProperty') {
|
|
1159
|
-
return false;
|
|
1160
|
-
}
|
|
1161
|
-
const propertyName = getObjectPropertyName(property);
|
|
1162
|
-
return (propertyName !== null &&
|
|
1163
|
-
cssShorthand.isUnsupportedProperty(propertyName));
|
|
1164
|
-
})) {
|
|
1165
|
-
return computedStatus();
|
|
1166
|
-
}
|
|
1167
|
-
let prop;
|
|
1168
|
-
for (let index = objExpr.properties.length - 1; index >= 0; index--) {
|
|
1169
|
-
const candidate = objExpr.properties[index];
|
|
1170
|
-
if (candidate.type === 'SpreadElement') {
|
|
1171
|
-
return computedStatus();
|
|
1172
|
-
}
|
|
1173
|
-
if (candidate.type === 'ObjectProperty' &&
|
|
1174
|
-
(getObjectPropertyName(candidate) === childKey ||
|
|
1175
|
-
getObjectPropertyName(candidate) === (cssShorthand === null || cssShorthand === void 0 ? void 0 : cssShorthand.shorthand))) {
|
|
1176
|
-
prop = candidate;
|
|
1177
|
-
break;
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
if (prop &&
|
|
1181
|
-
cssShorthand &&
|
|
1182
|
-
getObjectPropertyName(prop) === cssShorthand.shorthand) {
|
|
1183
|
-
const shorthandValue = prop.value;
|
|
1184
|
-
if (!(0, exports.isStaticValue)(shorthandValue, { allowSpecialValues: false })) {
|
|
1185
|
-
return computedStatus();
|
|
1186
|
-
}
|
|
1187
|
-
const staticShorthandValue = (0, exports.extractStaticValue)(shorthandValue, {
|
|
1188
|
-
allowSpecialValues: false,
|
|
1189
|
-
});
|
|
1190
|
-
const parsed = cssShorthand.parse(staticShorthandValue);
|
|
1191
|
-
return parsed ? staticStatus(parsed[childKey], null) : computedStatus();
|
|
1192
|
-
}
|
|
1193
|
-
if (!prop) {
|
|
1194
|
-
// Property not set in the object, can be added
|
|
1195
|
-
return staticStatus(undefined, null);
|
|
1196
|
-
}
|
|
1197
|
-
const propValue = prop.value;
|
|
1198
|
-
if (parentKey === 'style' && childKey === BORDER_RADIUS_SHORTHAND) {
|
|
1199
|
-
return getBorderRadiusShorthandStatus({
|
|
1200
|
-
propValue,
|
|
1201
|
-
ast,
|
|
1202
|
-
videoConfigValues,
|
|
934
|
+
return targets.map(({ line, column }) => {
|
|
935
|
+
var _a;
|
|
936
|
+
var _b;
|
|
937
|
+
const lineMatches = nodes.filter((node) => {
|
|
938
|
+
var _a;
|
|
939
|
+
return ((_a = node.location) === null || _a === void 0 ? void 0 : _a.line) === line;
|
|
1203
940
|
});
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
|
|
1208
|
-
node: propValue,
|
|
1209
|
-
videoConfigValues,
|
|
941
|
+
const exactMatches = lineMatches.filter((node) => {
|
|
942
|
+
var _a;
|
|
943
|
+
return ((_a = node.location) === null || _a === void 0 ? void 0 : _a.column) === column;
|
|
1210
944
|
});
|
|
1211
|
-
return
|
|
1212
|
-
? staticStatus(numericExpression.value, numericExpression)
|
|
1213
|
-
: (0, exports.getComputedStatus)(propValue, ast, videoConfigValues);
|
|
1214
|
-
}
|
|
1215
|
-
const propStatus = (0, exports.extractStaticValue)(propValue, staticValueOptions);
|
|
1216
|
-
if (!validateStyleValue(childKey, propStatus)) {
|
|
1217
|
-
return computedStatus();
|
|
1218
|
-
}
|
|
1219
|
-
return staticStatus(propStatus, null);
|
|
1220
|
-
};
|
|
1221
|
-
const computeEffectsForJsx = ({ ast, jsxElement, effects, videoConfigValues, }) => {
|
|
1222
|
-
return effects.map((effect, effectIndex) => (0, can_update_effect_props_1.computeEffectPropStatus)({
|
|
1223
|
-
ast,
|
|
1224
|
-
jsx: jsxElement,
|
|
1225
|
-
effectIndex,
|
|
1226
|
-
keys: effect,
|
|
1227
|
-
videoConfigValues,
|
|
1228
|
-
}));
|
|
1229
|
-
};
|
|
1230
|
-
const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys, assetKeys, videoConfigValues, }) => {
|
|
1231
|
-
// A JSX spread attribute ({...props}) is invisible to the parser and may
|
|
1232
|
-
// set or override every prop that is not explicitly written after it.
|
|
1233
|
-
// Affected props are treated as computed so the runtime values pass
|
|
1234
|
-
// through untouched and Visual Mode does not offer to edit them.
|
|
1235
|
-
// Attributes written after the last spread win at runtime and can be
|
|
1236
|
-
// parsed as usual.
|
|
1237
|
-
const lastSpreadIndex = jsxElement.attributes.reduce((highest, attr, index) => attr.type === 'JSXSpreadAttribute' ? index : highest, -1);
|
|
1238
|
-
const allProps = getPropsStatus(jsxElement, ast, videoConfigValues, assetKeys);
|
|
1239
|
-
const filteredProps = {};
|
|
1240
|
-
const mixedBorderRadius = hasMixedBorderRadiusRepresentation(jsxElement);
|
|
1241
|
-
for (const key of keys) {
|
|
1242
|
-
if (mixedBorderRadius &&
|
|
1243
|
-
key.startsWith('style.') &&
|
|
1244
|
-
BORDER_RADIUS_PROPERTIES.has(key.slice('style.'.length))) {
|
|
1245
|
-
filteredProps[key] = computedStatus();
|
|
1246
|
-
continue;
|
|
1247
|
-
}
|
|
1248
|
-
if (key === 'children') {
|
|
1249
|
-
const childrenAttrIndex = jsxElement.attributes.findIndex((attr) => attr.type === 'JSXAttribute' &&
|
|
1250
|
-
attr.name.type === 'JSXIdentifier' &&
|
|
1251
|
-
attr.name.name === 'children');
|
|
1252
|
-
if (childrenAttrIndex !== -1 && childrenAttrIndex < lastSpreadIndex) {
|
|
1253
|
-
// A later spread may override the children attribute
|
|
1254
|
-
filteredProps[key] = computedStatus();
|
|
1255
|
-
continue;
|
|
1256
|
-
}
|
|
1257
|
-
const staticChildrenAttribute = (0, exports.getStaticJsxChildrenAttribute)(jsxElement);
|
|
1258
|
-
if (staticChildrenAttribute) {
|
|
1259
|
-
filteredProps[key] = staticStatus(staticChildrenAttribute.value, null);
|
|
1260
|
-
continue;
|
|
1261
|
-
}
|
|
1262
|
-
if ((0, exports.hasJsxChildrenAttribute)(jsxElement)) {
|
|
1263
|
-
filteredProps[key] = computedStatus();
|
|
1264
|
-
continue;
|
|
1265
|
-
}
|
|
1266
|
-
// JSX element children are compiled after any spread and win over
|
|
1267
|
-
// it. Only if the element body is empty may the spread provide the
|
|
1268
|
-
// children.
|
|
1269
|
-
const hasMeaningfulJsxChildren = jsxElementNode.children.some((candidate) => !(candidate.type === 'JSXText' && candidate.value.trim() === ''));
|
|
1270
|
-
if (!hasMeaningfulJsxChildren && lastSpreadIndex !== -1) {
|
|
1271
|
-
filteredProps[key] = computedStatus();
|
|
1272
|
-
continue;
|
|
1273
|
-
}
|
|
1274
|
-
const staticTextContent = (0, exports.getStaticJsxTextContent)(jsxElementNode);
|
|
1275
|
-
filteredProps[key] = staticTextContent
|
|
1276
|
-
? staticStatus(staticTextContent.value, null)
|
|
1277
|
-
: computedStatus();
|
|
1278
|
-
continue;
|
|
1279
|
-
}
|
|
1280
|
-
const dotIndex = key.indexOf('.');
|
|
1281
|
-
if (dotIndex !== -1) {
|
|
1282
|
-
filteredProps[key] = getNestedPropStatus({
|
|
1283
|
-
jsxElement,
|
|
1284
|
-
ast,
|
|
1285
|
-
parentKey: key.slice(0, dotIndex),
|
|
1286
|
-
childKey: key.slice(dotIndex + 1),
|
|
1287
|
-
videoConfigValues,
|
|
1288
|
-
allowSpecialValues: assetKeys.includes(key),
|
|
1289
|
-
lastSpreadIndex,
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
else if (key in allProps) {
|
|
1293
|
-
filteredProps[key] = allProps[key];
|
|
1294
|
-
}
|
|
1295
|
-
else if (lastSpreadIndex !== -1) {
|
|
1296
|
-
// The spread may provide this prop
|
|
1297
|
-
filteredProps[key] = computedStatus();
|
|
1298
|
-
}
|
|
1299
|
-
else {
|
|
1300
|
-
filteredProps[key] = staticStatus(undefined, null);
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
return filteredProps;
|
|
1304
|
-
};
|
|
1305
|
-
const computeSequencePropsStatusFromAstAndIdentifiers = ({ ast, nodePath, componentIdentity, keys, assetKeys, effects, videoConfigIdentifierValues, }) => {
|
|
1306
|
-
var _a;
|
|
1307
|
-
const jsxPath = (0, exports.findJsxElementPathAtNodePath)(ast, nodePath);
|
|
1308
|
-
const jsxElementNode = jsxPath ? getJsxElementNodeFromJsxPath(jsxPath) : null;
|
|
1309
|
-
const jsxElement = (_a = jsxElementNode === null || jsxElementNode === void 0 ? void 0 : jsxElementNode.openingElement) !== null && _a !== void 0 ? _a : null;
|
|
1310
|
-
if (!jsxPath || !jsxElement || !jsxElementNode) {
|
|
1311
|
-
throw new jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError();
|
|
1312
|
-
}
|
|
1313
|
-
if (!(0, jsx_component_identity_1.jsxComponentIdentitiesMatch)({
|
|
1314
|
-
expected: componentIdentity,
|
|
1315
|
-
actual: (0, jsx_component_identity_1.getJsxComponentIdentity)({ ast, jsxElement }),
|
|
1316
|
-
})) {
|
|
1317
|
-
throw new jsx_component_identity_1.JsxElementIdentityMismatchError();
|
|
1318
|
-
}
|
|
1319
|
-
const filteredProps = computeSequenceOnlyPropsRecord({
|
|
1320
|
-
jsxElement,
|
|
1321
|
-
jsxElementNode,
|
|
1322
|
-
ast,
|
|
1323
|
-
keys,
|
|
1324
|
-
assetKeys,
|
|
1325
|
-
videoConfigValues: videoConfigIdentifierValues,
|
|
1326
|
-
});
|
|
1327
|
-
const effectsStatuses = computeEffectsForJsx({
|
|
1328
|
-
ast,
|
|
1329
|
-
jsxElement,
|
|
1330
|
-
effects,
|
|
1331
|
-
videoConfigValues: videoConfigIdentifierValues,
|
|
1332
|
-
});
|
|
1333
|
-
const defaultKeyframeDisplayOffsetAdjustment = getDefaultFrameDisplayOffsetAdjustment({
|
|
1334
|
-
jsxPath,
|
|
1335
|
-
videoConfigValues: videoConfigIdentifierValues,
|
|
1336
|
-
});
|
|
1337
|
-
const addDefaultKeyframeDisplayOffsetAdjustment = (status) => {
|
|
1338
|
-
if (status.status !== 'static') {
|
|
1339
|
-
return status;
|
|
1340
|
-
}
|
|
1341
|
-
if (defaultKeyframeDisplayOffsetAdjustment === null) {
|
|
1342
|
-
return computedStatus();
|
|
1343
|
-
}
|
|
1344
|
-
if (defaultKeyframeDisplayOffsetAdjustment === 0) {
|
|
1345
|
-
return status;
|
|
1346
|
-
}
|
|
1347
|
-
return {
|
|
1348
|
-
...status,
|
|
1349
|
-
keyframeDisplayOffsetAdjustment: defaultKeyframeDisplayOffsetAdjustment,
|
|
1350
|
-
};
|
|
1351
|
-
};
|
|
1352
|
-
return {
|
|
1353
|
-
canUpdate: true,
|
|
1354
|
-
props: Object.fromEntries(Object.entries(filteredProps).map(([key, status]) => [
|
|
1355
|
-
key,
|
|
1356
|
-
addDefaultKeyframeDisplayOffsetAdjustment(status),
|
|
1357
|
-
])),
|
|
1358
|
-
effects: effectsStatuses.map((effectStatus) => effectStatus.canUpdate
|
|
1359
|
-
? {
|
|
1360
|
-
...effectStatus,
|
|
1361
|
-
props: Object.fromEntries(Object.entries(effectStatus.props).map(([key, status]) => [
|
|
1362
|
-
key,
|
|
1363
|
-
addDefaultKeyframeDisplayOffsetAdjustment(status),
|
|
1364
|
-
])),
|
|
1365
|
-
}
|
|
1366
|
-
: effectStatus),
|
|
1367
|
-
};
|
|
1368
|
-
};
|
|
1369
|
-
const computeSequencePropsStatusFromAst = ({ ast, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
|
|
1370
|
-
return computeSequencePropsStatusFromAstAndIdentifiers({
|
|
1371
|
-
ast,
|
|
1372
|
-
nodePath,
|
|
1373
|
-
componentIdentity,
|
|
1374
|
-
keys,
|
|
1375
|
-
assetKeys,
|
|
1376
|
-
effects,
|
|
1377
|
-
videoConfigIdentifierValues: (0, video_config_values_1.getVideoConfigIdentifierValues)({
|
|
1378
|
-
ast,
|
|
1379
|
-
videoConfigValues,
|
|
1380
|
-
}),
|
|
945
|
+
return ((_b = (_a = (exactMatches.length === 1 ? exactMatches[0] : lineMatches.at(-1))) === null || _a === void 0 ? void 0 : _a.nodePath) !== null && _b !== void 0 ? _b : null);
|
|
1381
946
|
});
|
|
1382
947
|
};
|
|
1383
|
-
exports.
|
|
948
|
+
exports.resolveSequencePropsNodePathsFromFilename = resolveSequencePropsNodePathsFromFilename;
|
|
1384
949
|
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
950
|
+
try {
|
|
951
|
+
return (0, codemods_1.getJsxNodeProps)({
|
|
952
|
+
project: { rootDir: '/', files: { 'source.tsx': fileContents } },
|
|
953
|
+
node: { filePath: 'source.tsx', nodePath },
|
|
954
|
+
componentIdentity,
|
|
955
|
+
keys,
|
|
956
|
+
assetKeys,
|
|
957
|
+
effectKeys: effects,
|
|
958
|
+
videoConfig: videoConfigValues !== null && videoConfigValues !== void 0 ? videoConfigValues : undefined,
|
|
1393
959
|
});
|
|
1394
|
-
cachedAst.videoConfigIdentifierValues.set(videoConfigCacheKey, videoConfigIdentifierValues);
|
|
1395
960
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
}
|
|
961
|
+
catch (error) {
|
|
962
|
+
if (error instanceof codemods_1.CodemodsInternals.JsxElementIdentityMismatchError) {
|
|
963
|
+
throw new jsx_component_identity_1.JsxElementIdentityMismatchError();
|
|
964
|
+
}
|
|
965
|
+
if (error instanceof codemods_1.CodemodsInternals.JsxElementNotFoundAtLocationError) {
|
|
966
|
+
throw new jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError();
|
|
967
|
+
}
|
|
968
|
+
throw error;
|
|
969
|
+
}
|
|
1405
970
|
};
|
|
1406
971
|
exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
|
|
1407
972
|
const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, assetKeys = [], effects, remotionRoot, videoConfigValues, }) => {
|
|
@@ -1429,9 +994,11 @@ const computeSequencePropsStatusFromFilenameByLocation = ({ fileName, line, colu
|
|
|
1429
994
|
fileName,
|
|
1430
995
|
action: 'read',
|
|
1431
996
|
});
|
|
1432
|
-
const
|
|
1433
|
-
|
|
1434
|
-
|
|
997
|
+
const [resolvedNodePath] = (0, exports.resolveSequencePropsNodePathsFromFilename)({
|
|
998
|
+
fileName,
|
|
999
|
+
targets: [{ line, column }],
|
|
1000
|
+
remotionRoot,
|
|
1001
|
+
});
|
|
1435
1002
|
if (!resolvedNodePath) {
|
|
1436
1003
|
return {
|
|
1437
1004
|
status: {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deleteEffectHandler = void 0;
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
|
+
const codemods_1 = require("@remotion/codemods");
|
|
5
6
|
const renderer_1 = require("@remotion/renderer");
|
|
6
|
-
const delete_effect_1 = require("../../codemods/delete-effect");
|
|
7
7
|
const file_watcher_1 = require("../../file-watcher");
|
|
8
8
|
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
9
9
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
@@ -32,25 +32,27 @@ const deleteEffectHandler = ({ input: effects, remotionRoot, logLevel }) => {
|
|
|
32
32
|
itemsByFileName.set(item.fileName, fileItems);
|
|
33
33
|
}
|
|
34
34
|
const updates = await Promise.all([...itemsByFileName.entries()].map(async ([fileName, fileItems]) => {
|
|
35
|
+
var _a;
|
|
36
|
+
var _b;
|
|
35
37
|
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
36
38
|
remotionRoot,
|
|
37
39
|
fileName,
|
|
38
40
|
action: 'modify',
|
|
39
41
|
});
|
|
40
42
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
:
|
|
50
|
-
|
|
51
|
-
sequenceNodePath: item.sequenceNodePath.nodePath,
|
|
52
|
-
}),
|
|
43
|
+
const result = await (0, codemods_1.deleteEffects)({
|
|
44
|
+
project: {
|
|
45
|
+
files: { [absolutePath]: fileContents },
|
|
46
|
+
rootDir: remotionRoot,
|
|
47
|
+
},
|
|
48
|
+
effects: fileItems.map((item) => ({
|
|
49
|
+
filePath: absolutePath,
|
|
50
|
+
nodePath: item.sequenceNodePath.nodePath,
|
|
51
|
+
effectIndex: item.type === 'all-effects' ? null : item.effectIndex,
|
|
52
|
+
})),
|
|
53
53
|
});
|
|
54
|
+
const output = (_b = (_a = result.changes[0]) === null || _a === void 0 ? void 0 : _a.nextContents) !== null && _b !== void 0 ? _b : fileContents;
|
|
55
|
+
const { formatted, effectLabels, logLines } = result.editDetails[0];
|
|
54
56
|
return {
|
|
55
57
|
absolutePath,
|
|
56
58
|
fileRelativeToRoot,
|