@remotion/studio-server 4.0.467 → 4.0.469
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.js +6 -9
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +61 -0
- package/dist/codemods/update-keyframes/update-keyframes.js +398 -0
- package/dist/helpers/resolve-file-inside-project.d.ts +8 -0
- package/dist/helpers/resolve-file-inside-project.js +25 -0
- package/dist/preview-server/routes/apply-visual-control-change.js +6 -9
- package/dist/preview-server/routes/can-update-effect-props.js +6 -9
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +0 -9
- package/dist/preview-server/routes/can-update-sequence-props.js +187 -41
- package/dist/preview-server/routes/delete-effect.js +6 -9
- package/dist/preview-server/routes/delete-jsx-node.js +6 -9
- package/dist/preview-server/routes/duplicate-jsx-node.js +6 -9
- package/dist/preview-server/routes/save-effect-props.js +6 -9
- package/dist/preview-server/routes/save-sequence-props.js +13 -13
- package/package.json +6 -6
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.applyCodemodToFile = exports.resolveFilePathFromSymbolicatedStack = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const
|
|
5
|
+
const resolve_file_inside_project_1 = require("../helpers/resolve-file-inside-project");
|
|
9
6
|
const can_update_default_props_1 = require("../preview-server/routes/can-update-default-props");
|
|
10
7
|
const duplicate_composition_1 = require("./duplicate-composition");
|
|
11
8
|
const resolveFilePathFromSymbolicatedStack = (remotionRoot, stack) => {
|
|
12
9
|
if (!stack.originalFileName) {
|
|
13
10
|
throw new Error('Could not determine the file where this composition is defined');
|
|
14
11
|
}
|
|
15
|
-
const absolutePath =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
12
|
+
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
13
|
+
remotionRoot,
|
|
14
|
+
fileName: stack.originalFileName,
|
|
15
|
+
action: 'apply codemod to',
|
|
16
|
+
});
|
|
20
17
|
if (!(0, node_fs_1.existsSync)(absolutePath)) {
|
|
21
18
|
throw new Error(`File not found: ${stack.originalFileName}`);
|
|
22
19
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SequenceNodePath } from 'remotion';
|
|
2
|
+
export type KeyframeOperation = {
|
|
3
|
+
type: 'add';
|
|
4
|
+
frame: number;
|
|
5
|
+
value: unknown;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'remove';
|
|
8
|
+
frame: number;
|
|
9
|
+
};
|
|
10
|
+
export type SequenceKeyframeUpdate = {
|
|
11
|
+
key: string;
|
|
12
|
+
operation: KeyframeOperation;
|
|
13
|
+
};
|
|
14
|
+
export type EffectKeyframeUpdate = {
|
|
15
|
+
key: string;
|
|
16
|
+
operation: KeyframeOperation;
|
|
17
|
+
};
|
|
18
|
+
export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, }: {
|
|
19
|
+
input: string;
|
|
20
|
+
nodePath: SequenceNodePath;
|
|
21
|
+
updates: SequenceKeyframeUpdate[];
|
|
22
|
+
}) => {
|
|
23
|
+
serialized: string;
|
|
24
|
+
oldValueStrings: string[];
|
|
25
|
+
logLine: number;
|
|
26
|
+
};
|
|
27
|
+
export declare const updateSequenceKeyframes: ({ input, nodePath, updates, prettierConfigOverride, }: {
|
|
28
|
+
input: string;
|
|
29
|
+
nodePath: SequenceNodePath;
|
|
30
|
+
updates: SequenceKeyframeUpdate[];
|
|
31
|
+
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
32
|
+
}) => Promise<{
|
|
33
|
+
output: string;
|
|
34
|
+
formatted: boolean;
|
|
35
|
+
oldValueStrings: string[];
|
|
36
|
+
logLine: number;
|
|
37
|
+
}>;
|
|
38
|
+
export declare const updateEffectKeyframesAst: ({ input, sequenceNodePath, effectIndex, updates, }: {
|
|
39
|
+
input: string;
|
|
40
|
+
sequenceNodePath: SequenceNodePath;
|
|
41
|
+
effectIndex: number;
|
|
42
|
+
updates: EffectKeyframeUpdate[];
|
|
43
|
+
}) => {
|
|
44
|
+
serialized: string;
|
|
45
|
+
oldValueStrings: string[];
|
|
46
|
+
logLine: number;
|
|
47
|
+
effectCallee: string;
|
|
48
|
+
};
|
|
49
|
+
export declare const updateEffectKeyframes: ({ input, sequenceNodePath, effectIndex, updates, prettierConfigOverride, }: {
|
|
50
|
+
input: string;
|
|
51
|
+
sequenceNodePath: SequenceNodePath;
|
|
52
|
+
effectIndex: number;
|
|
53
|
+
updates: EffectKeyframeUpdate[];
|
|
54
|
+
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
55
|
+
}) => Promise<{
|
|
56
|
+
output: string;
|
|
57
|
+
formatted: boolean;
|
|
58
|
+
oldValueStrings: string[];
|
|
59
|
+
logLine: number;
|
|
60
|
+
effectCallee: string;
|
|
61
|
+
}>;
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.updateEffectKeyframes = exports.updateEffectKeyframesAst = exports.updateSequenceKeyframes = exports.updateSequenceKeyframesAst = void 0;
|
|
37
|
+
const recast = __importStar(require("recast"));
|
|
38
|
+
const can_update_sequence_props_1 = require("../../preview-server/routes/can-update-sequence-props");
|
|
39
|
+
const format_file_content_1 = require("../format-file-content");
|
|
40
|
+
const parse_ast_1 = require("../parse-ast");
|
|
41
|
+
const update_effect_props_1 = require("../update-effect-props/update-effect-props");
|
|
42
|
+
const update_nested_prop_1 = require("../update-nested-prop");
|
|
43
|
+
const b = recast.types.builders;
|
|
44
|
+
const getSupportedCallArgument = (arg) => {
|
|
45
|
+
if (arg === undefined ||
|
|
46
|
+
arg.type === 'ArgumentPlaceholder' ||
|
|
47
|
+
arg.type === 'JSXNamespacedName') {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return arg;
|
|
51
|
+
};
|
|
52
|
+
const getNumericValue = (node) => {
|
|
53
|
+
if (node.type === 'NumericLiteral') {
|
|
54
|
+
return node.value;
|
|
55
|
+
}
|
|
56
|
+
if (node.type === 'UnaryExpression' &&
|
|
57
|
+
(node.operator === '-' || node.operator === '+') &&
|
|
58
|
+
node.argument.type === 'NumericLiteral') {
|
|
59
|
+
return node.operator === '-' ? -node.argument.value : node.argument.value;
|
|
60
|
+
}
|
|
61
|
+
if (node.type === 'TSAsExpression') {
|
|
62
|
+
return getNumericValue(node.expression);
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const getInterpolationExpression = (node) => {
|
|
67
|
+
if (node.type === 'TSAsExpression') {
|
|
68
|
+
return getInterpolationExpression(node.expression);
|
|
69
|
+
}
|
|
70
|
+
if (node.type !== 'CallExpression' ||
|
|
71
|
+
node.callee.type !== 'Identifier' ||
|
|
72
|
+
(node.callee.name !== 'interpolate' &&
|
|
73
|
+
node.callee.name !== 'interpolateColors')) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const frameArg = getSupportedCallArgument(node.arguments[0]);
|
|
77
|
+
const inputArg = node.arguments[1];
|
|
78
|
+
const outputArg = node.arguments[2];
|
|
79
|
+
if (!frameArg ||
|
|
80
|
+
!inputArg ||
|
|
81
|
+
!outputArg ||
|
|
82
|
+
inputArg.type !== 'ArrayExpression' ||
|
|
83
|
+
outputArg.type !== 'ArrayExpression' ||
|
|
84
|
+
inputArg.elements.length !== outputArg.elements.length) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const keyframes = [];
|
|
88
|
+
for (let i = 0; i < inputArg.elements.length; i++) {
|
|
89
|
+
const inputElement = inputArg.elements[i];
|
|
90
|
+
const outputElement = outputArg.elements[i];
|
|
91
|
+
if (!inputElement ||
|
|
92
|
+
!outputElement ||
|
|
93
|
+
inputElement.type === 'SpreadElement' ||
|
|
94
|
+
outputElement.type === 'SpreadElement') {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const frame = getNumericValue(inputElement);
|
|
98
|
+
if (frame === null || !(0, can_update_sequence_props_1.isStaticValue)(outputElement)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
keyframes.push({
|
|
102
|
+
frame,
|
|
103
|
+
output: outputElement,
|
|
104
|
+
value: (0, can_update_sequence_props_1.extractStaticValue)(outputElement),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (keyframes.length === 0) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const extraArgs = [];
|
|
111
|
+
for (const arg of node.arguments.slice(3)) {
|
|
112
|
+
const supportedArg = getSupportedCallArgument(arg);
|
|
113
|
+
if (!supportedArg) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
extraArgs.push(supportedArg);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
callee: node.callee,
|
|
120
|
+
input: frameArg,
|
|
121
|
+
extraArgs,
|
|
122
|
+
keyframes,
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
const getInterpolationCalleeForValues = ({ staticValue, newValue, }) => {
|
|
126
|
+
return b.identifier(typeof staticValue === 'string' && typeof newValue === 'string'
|
|
127
|
+
? 'interpolateColors'
|
|
128
|
+
: 'interpolate');
|
|
129
|
+
};
|
|
130
|
+
const createFrameExpression = (frame) => {
|
|
131
|
+
return (0, update_nested_prop_1.parseValueExpression)(frame);
|
|
132
|
+
};
|
|
133
|
+
const createInterpolateExpression = ({ callee, input, extraArgs, keyframes, }) => {
|
|
134
|
+
const sortedKeyframes = [...keyframes].sort((first, second) => first.frame - second.frame);
|
|
135
|
+
return b.callExpression(callee, [
|
|
136
|
+
input,
|
|
137
|
+
b.arrayExpression(sortedKeyframes.map((keyframe) => createFrameExpression(keyframe.frame))),
|
|
138
|
+
b.arrayExpression(sortedKeyframes.map((keyframe) => keyframe.output)),
|
|
139
|
+
...extraArgs,
|
|
140
|
+
]);
|
|
141
|
+
};
|
|
142
|
+
const addKeyframe = ({ expression, frame, value, }) => {
|
|
143
|
+
const existing = getInterpolationExpression(expression);
|
|
144
|
+
const newOutput = (0, update_nested_prop_1.parseValueExpression)(value);
|
|
145
|
+
if (existing) {
|
|
146
|
+
const existingIndex = existing.keyframes.findIndex((keyframe) => keyframe.frame === frame);
|
|
147
|
+
const nextKeyframes = existingIndex === -1
|
|
148
|
+
? [...existing.keyframes, { frame, output: newOutput, value }]
|
|
149
|
+
: existing.keyframes.map((keyframe, index) => index === existingIndex
|
|
150
|
+
? { frame, output: newOutput, value }
|
|
151
|
+
: keyframe);
|
|
152
|
+
return createInterpolateExpression({
|
|
153
|
+
callee: existing.callee,
|
|
154
|
+
input: existing.input,
|
|
155
|
+
extraArgs: existing.extraArgs,
|
|
156
|
+
keyframes: nextKeyframes,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (!(0, can_update_sequence_props_1.isStaticValue)(expression)) {
|
|
160
|
+
throw new Error('Cannot add keyframe to computed expression');
|
|
161
|
+
}
|
|
162
|
+
const staticValue = (0, can_update_sequence_props_1.extractStaticValue)(expression);
|
|
163
|
+
const staticOutput = (0, update_nested_prop_1.parseValueExpression)(staticValue);
|
|
164
|
+
const keyframes = frame === 0
|
|
165
|
+
? [{ frame, output: newOutput, value }]
|
|
166
|
+
: [
|
|
167
|
+
{ frame: 0, output: staticOutput, value: staticValue },
|
|
168
|
+
{ frame, output: newOutput, value },
|
|
169
|
+
];
|
|
170
|
+
return createInterpolateExpression({
|
|
171
|
+
callee: getInterpolationCalleeForValues({
|
|
172
|
+
staticValue,
|
|
173
|
+
newValue: value,
|
|
174
|
+
}),
|
|
175
|
+
input: b.identifier('frame'),
|
|
176
|
+
extraArgs: [],
|
|
177
|
+
keyframes,
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
const removeKeyframe = ({ expression, frame, }) => {
|
|
181
|
+
const existing = getInterpolationExpression(expression);
|
|
182
|
+
if (!existing) {
|
|
183
|
+
throw new Error('Cannot remove keyframe from non-interpolated expression');
|
|
184
|
+
}
|
|
185
|
+
const keyframeIndex = existing.keyframes.findIndex((keyframe) => keyframe.frame === frame);
|
|
186
|
+
if (keyframeIndex === -1) {
|
|
187
|
+
throw new Error(`Cannot remove keyframe at frame ${frame}: not found`);
|
|
188
|
+
}
|
|
189
|
+
const nextKeyframes = existing.keyframes.filter((_keyframe, index) => index !== keyframeIndex);
|
|
190
|
+
return createInterpolateExpression({
|
|
191
|
+
callee: existing.callee,
|
|
192
|
+
input: existing.input,
|
|
193
|
+
extraArgs: existing.extraArgs,
|
|
194
|
+
keyframes: nextKeyframes,
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
const applyKeyframeOperation = ({ expression, operation, }) => {
|
|
198
|
+
if (operation.type === 'add') {
|
|
199
|
+
return addKeyframe({
|
|
200
|
+
expression,
|
|
201
|
+
frame: operation.frame,
|
|
202
|
+
value: operation.value,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return removeKeyframe({ expression, frame: operation.frame });
|
|
206
|
+
};
|
|
207
|
+
const getExpressionFromJsxAttribute = (attr) => {
|
|
208
|
+
if (!attr.value) {
|
|
209
|
+
return b.booleanLiteral(true);
|
|
210
|
+
}
|
|
211
|
+
if (attr.value.type === 'StringLiteral') {
|
|
212
|
+
return attr.value;
|
|
213
|
+
}
|
|
214
|
+
if (attr.value.type !== 'JSXExpressionContainer') {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const { expression } = attr.value;
|
|
218
|
+
if (expression.type === 'JSXEmptyExpression') {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
return expression;
|
|
222
|
+
};
|
|
223
|
+
const findJsxAttribute = (attributes, name) => {
|
|
224
|
+
const attrIndex = attributes.findIndex((candidate) => {
|
|
225
|
+
if (candidate.type === 'JSXSpreadAttribute') {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
if (candidate.name.type === 'JSXNamespacedName') {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
return candidate.name.name === name;
|
|
232
|
+
});
|
|
233
|
+
const foundAttr = attrIndex === -1 ? undefined : attributes[attrIndex];
|
|
234
|
+
return {
|
|
235
|
+
attrIndex,
|
|
236
|
+
attr: foundAttr && foundAttr.type === 'JSXAttribute'
|
|
237
|
+
? foundAttr
|
|
238
|
+
: undefined,
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
const findObjectProperty = (objExpr, propertyName) => {
|
|
242
|
+
const propIndex = objExpr.properties.findIndex((prop) => prop.type === 'ObjectProperty' &&
|
|
243
|
+
((prop.key.type === 'Identifier' && prop.key.name === propertyName) ||
|
|
244
|
+
(prop.key.type === 'StringLiteral' && prop.key.value === propertyName)));
|
|
245
|
+
return {
|
|
246
|
+
propIndex,
|
|
247
|
+
prop: propIndex === -1
|
|
248
|
+
? undefined
|
|
249
|
+
: objExpr.properties[propIndex],
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
const getObjectExpression = (attr) => {
|
|
253
|
+
if (!attr.value || attr.value.type !== 'JSXExpressionContainer') {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
if (attr.value.expression.type !== 'ObjectExpression') {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
return attr.value.expression;
|
|
260
|
+
};
|
|
261
|
+
const getSequenceWritableProp = ({ attributes, key, }) => {
|
|
262
|
+
const dotIndex = key.indexOf('.');
|
|
263
|
+
if (dotIndex === -1) {
|
|
264
|
+
const { attr: topLevelAttr } = findJsxAttribute(attributes, key);
|
|
265
|
+
if (!topLevelAttr) {
|
|
266
|
+
throw new Error(`Cannot update keyframes: "${key}" is not set`);
|
|
267
|
+
}
|
|
268
|
+
const expression = getExpressionFromJsxAttribute(topLevelAttr);
|
|
269
|
+
if (!expression) {
|
|
270
|
+
throw new Error(`Cannot update keyframes: "${key}" is computed`);
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
expression,
|
|
274
|
+
setExpression: (nextExpression) => {
|
|
275
|
+
topLevelAttr.value = b.jsxExpressionContainer(nextExpression);
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const parentKey = key.slice(0, dotIndex);
|
|
280
|
+
const childKey = key.slice(dotIndex + 1);
|
|
281
|
+
const { attr: parentAttr } = findJsxAttribute(attributes, parentKey);
|
|
282
|
+
if (!parentAttr) {
|
|
283
|
+
throw new Error(`Cannot update keyframes: "${parentKey}" is not set`);
|
|
284
|
+
}
|
|
285
|
+
const objExpr = getObjectExpression(parentAttr);
|
|
286
|
+
if (!objExpr) {
|
|
287
|
+
throw new Error(`Cannot update keyframes: "${parentKey}" is computed`);
|
|
288
|
+
}
|
|
289
|
+
const { prop } = findObjectProperty(objExpr, childKey);
|
|
290
|
+
if (!prop) {
|
|
291
|
+
throw new Error(`Cannot update keyframes: "${key}" is not set`);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
expression: prop.value,
|
|
295
|
+
setExpression: (nextExpression) => {
|
|
296
|
+
prop.value = nextExpression;
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
const updateSequenceKeyframesAst = ({ input, nodePath, updates, }) => {
|
|
301
|
+
var _a;
|
|
302
|
+
var _b;
|
|
303
|
+
const ast = (0, parse_ast_1.parseAst)(input);
|
|
304
|
+
const node = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, nodePath);
|
|
305
|
+
if (!node) {
|
|
306
|
+
throw new Error('Could not find a JSX element at the specified location to update keyframes');
|
|
307
|
+
}
|
|
308
|
+
if (!node.attributes) {
|
|
309
|
+
node.attributes = [];
|
|
310
|
+
}
|
|
311
|
+
const oldValueStrings = [];
|
|
312
|
+
for (const update of updates) {
|
|
313
|
+
const prop = getSequenceWritableProp({
|
|
314
|
+
attributes: node.attributes,
|
|
315
|
+
key: update.key,
|
|
316
|
+
});
|
|
317
|
+
oldValueStrings.push(recast.print(prop.expression).code);
|
|
318
|
+
prop.setExpression(applyKeyframeOperation({
|
|
319
|
+
expression: prop.expression,
|
|
320
|
+
operation: update.operation,
|
|
321
|
+
}));
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
serialized: (0, parse_ast_1.serializeAst)(ast),
|
|
325
|
+
oldValueStrings,
|
|
326
|
+
logLine: (_b = (_a = node.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _b !== void 0 ? _b : 1,
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
exports.updateSequenceKeyframesAst = updateSequenceKeyframesAst;
|
|
330
|
+
const updateSequenceKeyframes = async ({ input, nodePath, updates, prettierConfigOverride, }) => {
|
|
331
|
+
const { serialized, oldValueStrings, logLine } = (0, exports.updateSequenceKeyframesAst)({
|
|
332
|
+
input,
|
|
333
|
+
nodePath,
|
|
334
|
+
updates,
|
|
335
|
+
});
|
|
336
|
+
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
337
|
+
input: serialized,
|
|
338
|
+
prettierConfigOverride,
|
|
339
|
+
});
|
|
340
|
+
return { output, formatted, oldValueStrings, logLine };
|
|
341
|
+
};
|
|
342
|
+
exports.updateSequenceKeyframes = updateSequenceKeyframes;
|
|
343
|
+
const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, updates, }) => {
|
|
344
|
+
var _a, _b;
|
|
345
|
+
var _c, _d, _e;
|
|
346
|
+
const ast = (0, parse_ast_1.parseAst)(input);
|
|
347
|
+
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath);
|
|
348
|
+
if (!jsx) {
|
|
349
|
+
throw new Error('Could not find a JSX element at the specified location to update effect keyframes');
|
|
350
|
+
}
|
|
351
|
+
const attr = (0, update_effect_props_1.findEffectsAttr)((_c = jsx.attributes) !== null && _c !== void 0 ? _c : []);
|
|
352
|
+
if (!attr) {
|
|
353
|
+
throw new Error('Could not find effects on the target JSX element');
|
|
354
|
+
}
|
|
355
|
+
const found = (0, update_effect_props_1.findEffectCallExpression)({ attr, effectIndex });
|
|
356
|
+
if (found.kind === 'error') {
|
|
357
|
+
throw new Error(`Cannot update effect keyframe: ${found.reason}`);
|
|
358
|
+
}
|
|
359
|
+
const { call, callee: effectCallee } = found;
|
|
360
|
+
if (call.arguments.length === 0 ||
|
|
361
|
+
call.arguments[0].type !== 'ObjectExpression') {
|
|
362
|
+
throw new Error('Cannot update effect keyframe: computed');
|
|
363
|
+
}
|
|
364
|
+
const objExpr = call.arguments[0];
|
|
365
|
+
const oldValueStrings = [];
|
|
366
|
+
for (const update of updates) {
|
|
367
|
+
const { prop } = findObjectProperty(objExpr, update.key);
|
|
368
|
+
if (!prop) {
|
|
369
|
+
throw new Error(`Cannot update keyframes: "${update.key}" is not set`);
|
|
370
|
+
}
|
|
371
|
+
oldValueStrings.push(recast.print(prop.value).code);
|
|
372
|
+
prop.value = applyKeyframeOperation({
|
|
373
|
+
expression: prop.value,
|
|
374
|
+
operation: update.operation,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
serialized: (0, parse_ast_1.serializeAst)(ast),
|
|
379
|
+
oldValueStrings,
|
|
380
|
+
logLine: (_e = (_d = (_a = call.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _d !== void 0 ? _d : (_b = jsx.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _e !== void 0 ? _e : 1,
|
|
381
|
+
effectCallee,
|
|
382
|
+
};
|
|
383
|
+
};
|
|
384
|
+
exports.updateEffectKeyframesAst = updateEffectKeyframesAst;
|
|
385
|
+
const updateEffectKeyframes = async ({ input, sequenceNodePath, effectIndex, updates, prettierConfigOverride, }) => {
|
|
386
|
+
const { serialized, oldValueStrings, logLine, effectCallee } = (0, exports.updateEffectKeyframesAst)({
|
|
387
|
+
input,
|
|
388
|
+
sequenceNodePath,
|
|
389
|
+
effectIndex,
|
|
390
|
+
updates,
|
|
391
|
+
});
|
|
392
|
+
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
393
|
+
input: serialized,
|
|
394
|
+
prettierConfigOverride,
|
|
395
|
+
});
|
|
396
|
+
return { output, formatted, oldValueStrings, logLine, effectCallee };
|
|
397
|
+
};
|
|
398
|
+
exports.updateEffectKeyframes = updateEffectKeyframes;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveFileInsideProject = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const formatOutsideProjectError = ({ action, fileName, absolutePath, remotionRoot, }) => `Cannot ${action} a file outside the project: "${fileName}" resolves to "${absolutePath}", but the project root is "${remotionRoot}".`;
|
|
9
|
+
const resolveFileInsideProject = ({ remotionRoot, fileName, action, }) => {
|
|
10
|
+
const resolvedRemotionRoot = node_path_1.default.resolve(remotionRoot);
|
|
11
|
+
const absolutePath = node_path_1.default.resolve(resolvedRemotionRoot, fileName);
|
|
12
|
+
const fileRelativeToRoot = node_path_1.default.relative(resolvedRemotionRoot, absolutePath);
|
|
13
|
+
if (fileRelativeToRoot === '..' ||
|
|
14
|
+
fileRelativeToRoot.startsWith(`..${node_path_1.default.sep}`) ||
|
|
15
|
+
node_path_1.default.isAbsolute(fileRelativeToRoot)) {
|
|
16
|
+
throw new Error(formatOutsideProjectError({
|
|
17
|
+
action,
|
|
18
|
+
fileName,
|
|
19
|
+
absolutePath,
|
|
20
|
+
remotionRoot: resolvedRemotionRoot,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
return { absolutePath, fileRelativeToRoot };
|
|
24
|
+
};
|
|
25
|
+
exports.resolveFileInsideProject = resolveFileInsideProject;
|
|
@@ -32,18 +32,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.applyVisualControlHandler = void 0;
|
|
40
37
|
const node_fs_1 = require("node:fs");
|
|
41
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
42
38
|
const renderer_1 = require("@remotion/renderer");
|
|
43
39
|
const recast = __importStar(require("recast"));
|
|
44
40
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
45
41
|
const recast_mods_1 = require("../../codemods/recast-mods");
|
|
46
42
|
const file_watcher_1 = require("../../file-watcher");
|
|
43
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
47
44
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
48
45
|
const live_events_1 = require("../live-events");
|
|
49
46
|
const undo_stack_1 = require("../undo-stack");
|
|
@@ -71,11 +68,11 @@ const getVisualControlChangeLine = (file, changeId) => {
|
|
|
71
68
|
};
|
|
72
69
|
const applyVisualControlHandler = async ({ input: { fileName, changes }, remotionRoot, logLevel }) => {
|
|
73
70
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[apply-visual-control] Received request for ${fileName} with ${changes.length} changes`);
|
|
74
|
-
const absolutePath =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
71
|
+
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
72
|
+
remotionRoot,
|
|
73
|
+
fileName,
|
|
74
|
+
action: 'apply visual control change to',
|
|
75
|
+
});
|
|
79
76
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
80
77
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
81
78
|
const logLine = changes.length > 0 ? getVisualControlChangeLine(ast, changes[0].id) : 1;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.computeEffectPropsStatusesFromFile = exports.computeEffectPropsStatusesFromContent = exports.computeEffectPropStatus = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
10
6
|
const update_effect_props_1 = require("../../codemods/update-effect-props/update-effect-props");
|
|
7
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
11
8
|
const can_update_sequence_props_1 = require("./can-update-sequence-props");
|
|
12
9
|
const findEffectsAttr = (jsx) => {
|
|
13
10
|
for (const attr of jsx.attributes) {
|
|
@@ -129,11 +126,11 @@ const computeEffectPropsStatusesFromContent = ({ fileContents, sequenceNodePath,
|
|
|
129
126
|
};
|
|
130
127
|
exports.computeEffectPropsStatusesFromContent = computeEffectPropsStatusesFromContent;
|
|
131
128
|
const computeEffectPropsStatusesFromFile = ({ fileName, sequenceNodePath, effects, keysFor, remotionRoot, }) => {
|
|
132
|
-
const absolutePath =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
129
|
+
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
130
|
+
remotionRoot,
|
|
131
|
+
fileName,
|
|
132
|
+
action: 'read',
|
|
133
|
+
});
|
|
137
134
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
138
135
|
return (0, exports.computeEffectPropsStatusesFromContent)({
|
|
139
136
|
fileContents,
|
|
@@ -6,15 +6,6 @@ export declare const extractStaticValue: (node: Expression) => unknown;
|
|
|
6
6
|
export declare const getComputedStatus: (node: Expression) => CanUpdateSequencePropStatus;
|
|
7
7
|
export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
|
|
8
8
|
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
9
|
-
export declare const computeSequencePropsOnlyStatus: ({ fileName, nodePath, keys, remotionRoot, }: {
|
|
10
|
-
fileName: string;
|
|
11
|
-
nodePath: SequenceNodePath;
|
|
12
|
-
keys: string[];
|
|
13
|
-
remotionRoot: string;
|
|
14
|
-
}) => {
|
|
15
|
-
canUpdate: true;
|
|
16
|
-
props: Record<string, CanUpdateSequencePropStatus>;
|
|
17
|
-
};
|
|
18
9
|
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, keys, effects, }: {
|
|
19
10
|
fileContents: string;
|
|
20
11
|
nodePath: SequenceNodePath;
|
|
@@ -32,17 +32,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.
|
|
36
|
+
exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findJsxElementAtNodePath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
|
|
40
37
|
const node_fs_1 = require("node:fs");
|
|
41
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
42
38
|
const renderer_1 = require("@remotion/renderer");
|
|
43
39
|
const recast = __importStar(require("recast"));
|
|
44
40
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
45
41
|
const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
|
|
42
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
46
43
|
const jsx_element_not_found_at_location_error_1 = require("../jsx-element-not-found-at-location-error");
|
|
47
44
|
const can_update_effect_props_1 = require("./can-update-effect-props");
|
|
48
45
|
const isStaticValue = (node) => {
|
|
@@ -131,16 +128,170 @@ const getNumericValue = (node) => {
|
|
|
131
128
|
}
|
|
132
129
|
return null;
|
|
133
130
|
};
|
|
134
|
-
const
|
|
131
|
+
const getExtrapolateType = (node) => {
|
|
132
|
+
if (node.type === 'StringLiteral') {
|
|
133
|
+
if (node.value === 'extend' ||
|
|
134
|
+
node.value === 'identity' ||
|
|
135
|
+
node.value === 'clamp' ||
|
|
136
|
+
node.value === 'wrap') {
|
|
137
|
+
return node.value;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
if (node.type === 'TSAsExpression') {
|
|
142
|
+
return getExtrapolateType(node.expression);
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
};
|
|
146
|
+
const getKeyframeEasing = (node) => {
|
|
135
147
|
if (node.type === 'TSAsExpression') {
|
|
136
|
-
return
|
|
148
|
+
return getKeyframeEasing(node.expression);
|
|
149
|
+
}
|
|
150
|
+
if (node.type === 'MemberExpression' &&
|
|
151
|
+
node.object.type === 'Identifier' &&
|
|
152
|
+
node.object.name === 'Easing' &&
|
|
153
|
+
node.property.type === 'Identifier' &&
|
|
154
|
+
node.property.name === 'linear' &&
|
|
155
|
+
node.computed === false) {
|
|
156
|
+
return 'linear';
|
|
157
|
+
}
|
|
158
|
+
if (node.type !== 'CallExpression' ||
|
|
159
|
+
node.callee.type !== 'MemberExpression' ||
|
|
160
|
+
node.callee.object.type !== 'Identifier' ||
|
|
161
|
+
node.callee.object.name !== 'Easing' ||
|
|
162
|
+
node.callee.property.type !== 'Identifier' ||
|
|
163
|
+
node.callee.property.name !== 'bezier' ||
|
|
164
|
+
node.callee.computed) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
if (node.arguments.length !== 4) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
const values = node.arguments.map((arg) => {
|
|
171
|
+
if (arg.type === 'ArgumentPlaceholder' ||
|
|
172
|
+
arg.type === 'JSXNamespacedName' ||
|
|
173
|
+
arg.type === 'SpreadElement') {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
return getNumericValue(arg);
|
|
177
|
+
});
|
|
178
|
+
if (values.some((v) => v === null)) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return values;
|
|
182
|
+
};
|
|
183
|
+
const getKeyframeEasingArray = ({ easingNode, segments, }) => {
|
|
184
|
+
if (segments === 0) {
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
if (easingNode.type === 'TSAsExpression') {
|
|
188
|
+
return getKeyframeEasingArray({
|
|
189
|
+
easingNode: easingNode.expression,
|
|
190
|
+
segments,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (easingNode.type === 'ArrayExpression') {
|
|
194
|
+
if (easingNode.elements.length !== segments) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const parsed = easingNode.elements.map((element) => {
|
|
198
|
+
if (!element || element.type === 'SpreadElement') {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
return getKeyframeEasing(element);
|
|
202
|
+
});
|
|
203
|
+
if (parsed.some((value) => value === null)) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
return parsed;
|
|
207
|
+
}
|
|
208
|
+
const easing = getKeyframeEasing(easingNode);
|
|
209
|
+
if (!easing) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return new Array(segments).fill(easing);
|
|
213
|
+
};
|
|
214
|
+
const getInterpolationMetadata = (callExpression, keyframeCount) => {
|
|
215
|
+
const segments = Math.max(0, keyframeCount - 1);
|
|
216
|
+
if (callExpression.callee.type !== 'Identifier') {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
const defaultClamping = callExpression.callee.name === 'interpolateColors'
|
|
220
|
+
? {
|
|
221
|
+
left: 'clamp',
|
|
222
|
+
right: 'clamp',
|
|
223
|
+
}
|
|
224
|
+
: {
|
|
225
|
+
left: 'extend',
|
|
226
|
+
right: 'extend',
|
|
227
|
+
};
|
|
228
|
+
const defaults = {
|
|
229
|
+
easing: new Array(segments).fill('linear'),
|
|
230
|
+
clamping: defaultClamping,
|
|
231
|
+
};
|
|
232
|
+
if (callExpression.callee.name === 'interpolateColors') {
|
|
233
|
+
return defaults;
|
|
234
|
+
}
|
|
235
|
+
if (callExpression.callee.name !== 'interpolate') {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
const optionsArg = callExpression.arguments[3];
|
|
239
|
+
if (!optionsArg) {
|
|
240
|
+
return defaults;
|
|
241
|
+
}
|
|
242
|
+
if (optionsArg.type !== 'ObjectExpression') {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
let { easing } = defaults;
|
|
246
|
+
let { clamping } = defaults;
|
|
247
|
+
for (const property of optionsArg.properties) {
|
|
248
|
+
if (property.type !== 'ObjectProperty' || property.computed) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const key = property.key.type === 'Identifier'
|
|
252
|
+
? property.key.name
|
|
253
|
+
: property.key.type === 'StringLiteral'
|
|
254
|
+
? property.key.value
|
|
255
|
+
: null;
|
|
256
|
+
if (!key) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const value = property.value;
|
|
260
|
+
if (key === 'easing') {
|
|
261
|
+
const parsedEasing = getKeyframeEasingArray({
|
|
262
|
+
easingNode: value,
|
|
263
|
+
segments,
|
|
264
|
+
});
|
|
265
|
+
if (!parsedEasing) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
easing = parsedEasing;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (key === 'extrapolateLeft' || key === 'extrapolateRight') {
|
|
272
|
+
const extrapolateType = getExtrapolateType(value);
|
|
273
|
+
if (!extrapolateType) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
clamping =
|
|
277
|
+
key === 'extrapolateLeft'
|
|
278
|
+
? { ...clamping, left: extrapolateType }
|
|
279
|
+
: { ...clamping, right: extrapolateType };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return { easing, clamping };
|
|
283
|
+
};
|
|
284
|
+
const getInterpolationKeyframes = (node) => {
|
|
285
|
+
if (node.type === 'TSAsExpression') {
|
|
286
|
+
return getInterpolationKeyframes(node.expression);
|
|
137
287
|
}
|
|
138
288
|
if (node.type !== 'CallExpression') {
|
|
139
289
|
return undefined;
|
|
140
290
|
}
|
|
141
291
|
const callExpression = node;
|
|
142
292
|
if (callExpression.callee.type !== 'Identifier' ||
|
|
143
|
-
callExpression.callee.name !== 'interpolate'
|
|
293
|
+
(callExpression.callee.name !== 'interpolate' &&
|
|
294
|
+
callExpression.callee.name !== 'interpolateColors')) {
|
|
144
295
|
return undefined;
|
|
145
296
|
}
|
|
146
297
|
const inputArg = callExpression.arguments[1];
|
|
@@ -173,17 +324,30 @@ const getInterpolateKeyframes = (node) => {
|
|
|
173
324
|
value: (0, exports.extractStaticValue)(outputElement),
|
|
174
325
|
});
|
|
175
326
|
}
|
|
176
|
-
|
|
327
|
+
if (keyframes.length === 0) {
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
330
|
+
const metadata = getInterpolationMetadata(callExpression, keyframes.length);
|
|
331
|
+
if (!metadata) {
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
keyframes,
|
|
336
|
+
easing: metadata.easing,
|
|
337
|
+
clamping: metadata.clamping,
|
|
338
|
+
};
|
|
177
339
|
};
|
|
178
340
|
const getComputedStatus = (node) => {
|
|
179
|
-
const
|
|
180
|
-
if (!
|
|
341
|
+
const interpolation = getInterpolationKeyframes(node);
|
|
342
|
+
if (!interpolation) {
|
|
181
343
|
return { canUpdate: false, reason: 'computed' };
|
|
182
344
|
}
|
|
183
345
|
return {
|
|
184
346
|
canUpdate: false,
|
|
185
|
-
reason: '
|
|
186
|
-
keyframes,
|
|
347
|
+
reason: 'keyframed',
|
|
348
|
+
keyframes: interpolation.keyframes,
|
|
349
|
+
easing: interpolation.easing,
|
|
350
|
+
clamping: interpolation.clamping,
|
|
187
351
|
};
|
|
188
352
|
};
|
|
189
353
|
exports.getComputedStatus = getComputedStatus;
|
|
@@ -347,24 +511,6 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, keys, }) => {
|
|
|
347
511
|
}
|
|
348
512
|
return filteredProps;
|
|
349
513
|
};
|
|
350
|
-
const computeSequencePropsOnlyStatus = ({ fileName, nodePath, keys, remotionRoot, }) => {
|
|
351
|
-
const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
|
|
352
|
-
const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
|
|
353
|
-
if (fileRelativeToRoot.startsWith('..')) {
|
|
354
|
-
throw new Error('Cannot read a file outside the project');
|
|
355
|
-
}
|
|
356
|
-
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
357
|
-
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
358
|
-
const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
|
|
359
|
-
if (!jsxElement) {
|
|
360
|
-
throw new Error('Cannot compute sequence props: Could not find a JSX element at the specified location');
|
|
361
|
-
}
|
|
362
|
-
return {
|
|
363
|
-
canUpdate: true,
|
|
364
|
-
props: computeSequenceOnlyPropsRecord({ jsxElement, keys }),
|
|
365
|
-
};
|
|
366
|
-
};
|
|
367
|
-
exports.computeSequencePropsOnlyStatus = computeSequencePropsOnlyStatus;
|
|
368
514
|
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, effects, }) => {
|
|
369
515
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
370
516
|
const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
|
|
@@ -381,11 +527,11 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, e
|
|
|
381
527
|
};
|
|
382
528
|
exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
|
|
383
529
|
const computeSequencePropsStatus = ({ fileName, nodePath, keys, effects, remotionRoot, }) => {
|
|
384
|
-
const absolutePath =
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
}
|
|
530
|
+
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
531
|
+
remotionRoot,
|
|
532
|
+
fileName,
|
|
533
|
+
action: 'read',
|
|
534
|
+
});
|
|
389
535
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
390
536
|
return (0, exports.computeSequencePropsStatusFromContent)({
|
|
391
537
|
fileContents,
|
|
@@ -397,11 +543,11 @@ const computeSequencePropsStatus = ({ fileName, nodePath, keys, effects, remotio
|
|
|
397
543
|
exports.computeSequencePropsStatus = computeSequencePropsStatus;
|
|
398
544
|
const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, keys, effects, remotionRoot, logLevel, }) => {
|
|
399
545
|
try {
|
|
400
|
-
const absolutePath =
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
546
|
+
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
547
|
+
remotionRoot,
|
|
548
|
+
fileName,
|
|
549
|
+
action: 'read',
|
|
550
|
+
});
|
|
405
551
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
406
552
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
407
553
|
const resolvedNodePath = (0, exports.lineColumnToNodePath)(ast, line);
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.deleteEffectHandler = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const renderer_1 = require("@remotion/renderer");
|
|
10
6
|
const delete_effect_1 = require("../../codemods/delete-effect");
|
|
11
7
|
const file_watcher_1 = require("../../file-watcher");
|
|
8
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
12
9
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
13
10
|
const undo_stack_1 = require("../undo-stack");
|
|
14
11
|
const formatting_1 = require("./log-updates/formatting");
|
|
@@ -16,11 +13,11 @@ const log_update_1 = require("./log-updates/log-update");
|
|
|
16
13
|
const deleteEffectHandler = async ({ input: { fileName, sequenceNodePath, effectIndex }, remotionRoot, logLevel, }) => {
|
|
17
14
|
try {
|
|
18
15
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-effect] Received request for fileName="${fileName}" effectIndex=${effectIndex}`);
|
|
19
|
-
const absolutePath =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
16
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
17
|
+
remotionRoot,
|
|
18
|
+
fileName,
|
|
19
|
+
action: 'modify',
|
|
20
|
+
});
|
|
24
21
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
25
22
|
const { output, formatted, effectLabel, logLine } = await (0, delete_effect_1.deleteEffect)({
|
|
26
23
|
input: fileContents,
|
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.deleteJsxNodeHandler = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const renderer_1 = require("@remotion/renderer");
|
|
10
6
|
const delete_jsx_node_1 = require("../../codemods/delete-jsx-node");
|
|
11
7
|
const file_watcher_1 = require("../../file-watcher");
|
|
8
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
12
9
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
13
10
|
const undo_stack_1 = require("../undo-stack");
|
|
14
11
|
const log_update_1 = require("./log-updates/log-update");
|
|
15
12
|
const deleteJsxNodeHandler = async ({ input: { fileName, nodePath }, remotionRoot, logLevel }) => {
|
|
16
13
|
try {
|
|
17
14
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-jsx-node] Received request for fileName="${fileName}"`);
|
|
18
|
-
const absolutePath =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
15
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
16
|
+
remotionRoot,
|
|
17
|
+
fileName,
|
|
18
|
+
action: 'modify',
|
|
19
|
+
});
|
|
23
20
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
24
21
|
const { output, formatted, nodeLabel, logLine } = await (0, delete_jsx_node_1.deleteJsxNode)({
|
|
25
22
|
input: fileContents,
|
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.duplicateJsxNodeHandler = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const renderer_1 = require("@remotion/renderer");
|
|
10
6
|
const duplicate_jsx_node_1 = require("../../codemods/duplicate-jsx-node");
|
|
11
7
|
const file_watcher_1 = require("../../file-watcher");
|
|
8
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
12
9
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
13
10
|
const undo_stack_1 = require("../undo-stack");
|
|
14
11
|
const log_update_1 = require("./log-updates/log-update");
|
|
15
12
|
const duplicateJsxNodeHandler = async ({ input: { fileName, nodePath }, remotionRoot, logLevel }) => {
|
|
16
13
|
try {
|
|
17
14
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[duplicate-jsx-node] Received request for fileName="${fileName}"`);
|
|
18
|
-
const absolutePath =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
15
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
16
|
+
remotionRoot,
|
|
17
|
+
fileName,
|
|
18
|
+
action: 'modify',
|
|
19
|
+
});
|
|
23
20
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
24
21
|
const { output, formatted, nodeLabel, logLine } = await (0, duplicate_jsx_node_1.duplicateJsxNode)({
|
|
25
22
|
input: fileContents,
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.saveEffectPropsHandler = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const renderer_1 = require("@remotion/renderer");
|
|
10
6
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
11
7
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
12
8
|
const update_effect_props_1 = require("../../codemods/update-effect-props/update-effect-props");
|
|
13
9
|
const file_watcher_1 = require("../../file-watcher");
|
|
10
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
14
11
|
const undo_stack_1 = require("../undo-stack");
|
|
15
12
|
const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
|
|
16
13
|
const can_update_effect_props_1 = require("./can-update-effect-props");
|
|
@@ -21,11 +18,11 @@ const log_update_1 = require("./log-updates/log-update");
|
|
|
21
18
|
const save_props_mutex_1 = require("./save-props-mutex");
|
|
22
19
|
const saveEffectPropsHandler = ({ input: { fileName, sequenceNodePath, effectIndex, key, value, defaultValue, schema, clientId, }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
|
|
23
20
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-effect-props] Received request for fileName="${fileName}" effectIndex=${effectIndex} key="${key}"`);
|
|
24
|
-
const absolutePath =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
21
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
22
|
+
remotionRoot,
|
|
23
|
+
fileName,
|
|
24
|
+
action: 'modify',
|
|
25
|
+
});
|
|
29
26
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
30
27
|
const parsedDefault = defaultValue !== null ? JSON.parse(defaultValue) : null;
|
|
31
28
|
const { output, oldValueString, formatted, logLine, effectCallee, removedProps, } = await (0, update_effect_props_1.updateEffectProps)({
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.saveSequencePropsHandler = void 0;
|
|
7
4
|
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
5
|
const renderer_1 = require("@remotion/renderer");
|
|
10
6
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
11
7
|
const no_react_1 = require("remotion/no-react");
|
|
12
8
|
const update_sequence_props_1 = require("../../codemods/update-sequence-props/update-sequence-props");
|
|
13
9
|
const file_watcher_1 = require("../../file-watcher");
|
|
10
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
14
11
|
const undo_stack_1 = require("../undo-stack");
|
|
15
12
|
const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
|
|
16
13
|
const can_update_sequence_props_1 = require("./can-update-sequence-props");
|
|
@@ -19,11 +16,11 @@ const log_update_1 = require("./log-updates/log-update");
|
|
|
19
16
|
const save_props_mutex_1 = require("./save-props-mutex");
|
|
20
17
|
const saveSequencePropsHandler = ({ input: { fileName, nodePath, key, value, defaultValue, schema, clientId }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
|
|
21
18
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-sequence-props] Received request for fileName="${fileName}" key="${key}"`);
|
|
22
|
-
const absolutePath =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
19
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
20
|
+
remotionRoot,
|
|
21
|
+
fileName,
|
|
22
|
+
action: 'modify',
|
|
23
|
+
});
|
|
27
24
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
28
25
|
const { output, oldValueStrings, formatted, logLine, removedProps } = await (0, update_sequence_props_1.updateSequenceProps)({
|
|
29
26
|
input: fileContents,
|
|
@@ -89,12 +86,15 @@ const saveSequencePropsHandler = ({ input: { fileName, nodePath, key, value, def
|
|
|
89
86
|
addedProps: [],
|
|
90
87
|
});
|
|
91
88
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
92
|
-
const newStatus = (0, can_update_sequence_props_1.
|
|
93
|
-
|
|
89
|
+
const newStatus = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
|
|
90
|
+
fileContents: output,
|
|
94
91
|
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
95
92
|
nodePath: nodePath.nodePath,
|
|
96
|
-
|
|
93
|
+
effects: [],
|
|
97
94
|
});
|
|
98
|
-
return
|
|
95
|
+
return {
|
|
96
|
+
canUpdate: true,
|
|
97
|
+
props: newStatus.props,
|
|
98
|
+
};
|
|
99
99
|
});
|
|
100
100
|
exports.saveSequencePropsHandler = saveSequencePropsHandler;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/studio-server",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.469",
|
|
7
7
|
"description": "Run a Remotion Studio with a server backend",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"@babel/parser": "7.24.1",
|
|
28
28
|
"semver": "7.5.3",
|
|
29
29
|
"prettier": "3.8.1",
|
|
30
|
-
"remotion": "4.0.
|
|
30
|
+
"remotion": "4.0.469",
|
|
31
31
|
"recast": "0.23.11",
|
|
32
|
-
"@remotion/bundler": "4.0.
|
|
33
|
-
"@remotion/renderer": "4.0.
|
|
34
|
-
"@remotion/studio-shared": "4.0.
|
|
32
|
+
"@remotion/bundler": "4.0.469",
|
|
33
|
+
"@remotion/renderer": "4.0.469",
|
|
34
|
+
"@remotion/studio-shared": "4.0.469",
|
|
35
35
|
"memfs": "3.4.3",
|
|
36
36
|
"open": "8.4.2"
|
|
37
37
|
},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"ast-types": "0.16.1",
|
|
40
40
|
"react": "19.2.3",
|
|
41
41
|
"@types/semver": "7.5.3",
|
|
42
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
42
|
+
"@remotion/eslint-config-internal": "4.0.469",
|
|
43
43
|
"eslint": "9.19.0",
|
|
44
44
|
"@types/node": "20.12.14",
|
|
45
45
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|