@remotion/studio-server 4.0.474 → 4.0.476
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/duplicate-composition.js +9 -0
- package/dist/codemods/effect-param-expression.js +5 -8
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +10 -1
- package/dist/codemods/update-keyframes/update-keyframes.js +381 -29
- package/dist/helpers/imports.js +9 -4
- package/dist/helpers/resolve-composition-component.js +3 -2
- package/dist/preview-server/api-routes.js +2 -0
- package/dist/preview-server/routes/add-keyframes.d.ts +7 -0
- package/dist/preview-server/routes/add-keyframes.js +226 -0
- package/dist/preview-server/routes/can-update-default-props.js +6 -2
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +6 -2
- package/dist/preview-server/routes/can-update-sequence-props.js +55 -11
- package/dist/preview-server/routes/log-updates/format-prop-change.js +1 -1
- package/dist/preview-server/routes/log-updates/formatting.d.ts +6 -0
- package/dist/preview-server/routes/log-updates/formatting.js +256 -1
- package/dist/preview-server/routes/save-sequence-props.d.ts +18 -1
- package/dist/preview-server/routes/save-sequence-props.js +25 -17
- package/dist/preview-server/routes/update-effect-keyframe-settings.js +11 -5
- package/dist/preview-server/routes/update-sequence-keyframe-settings.js +11 -5
- package/dist/preview-server/undo-stack.d.ts +3 -1
- package/package.json +6 -6
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.parseAndApplyCodemod = exports.formatOutput = void 0;
|
|
37
|
+
const imports_1 = require("../helpers/imports");
|
|
37
38
|
const parse_ast_1 = require("./parse-ast");
|
|
38
39
|
const recast_mods_1 = require("./recast-mods");
|
|
39
40
|
const getPrettier = async () => {
|
|
@@ -71,6 +72,14 @@ const parseAndApplyCodemod = ({ input, codeMod, }) => {
|
|
|
71
72
|
if (changesMade.length === 0) {
|
|
72
73
|
throw new Error('Unable to calculate the changes needed for this file. Edit the file manually.');
|
|
73
74
|
}
|
|
75
|
+
if (codeMod.type === 'duplicate-composition' && codeMod.tag) {
|
|
76
|
+
(0, imports_1.ensureNamedImport)({
|
|
77
|
+
ast: newAst,
|
|
78
|
+
importedName: codeMod.tag,
|
|
79
|
+
sourcePath: 'remotion',
|
|
80
|
+
localName: codeMod.tag,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
74
83
|
const output = (0, parse_ast_1.serializeAst)(newAst);
|
|
75
84
|
return { changesMade, newContents: output };
|
|
76
85
|
};
|
|
@@ -39,10 +39,7 @@ const imports_1 = require("../helpers/imports");
|
|
|
39
39
|
const update_nested_prop_1 = require("./update-nested-prop");
|
|
40
40
|
const b = recast.types.builders;
|
|
41
41
|
const isNonLinearEasing = (easing) => easing !== 'linear';
|
|
42
|
-
const keyframedParamNeedsEasingImport = (param) =>
|
|
43
|
-
return (param.interpolationFunction !== 'interpolateColors' &&
|
|
44
|
-
param.easing.some(isNonLinearEasing));
|
|
45
|
-
};
|
|
42
|
+
const keyframedParamNeedsEasingImport = (param) => param.easing.some(isNonLinearEasing);
|
|
46
43
|
const getRequiredRemotionImportsForEffectParams = (params) => {
|
|
47
44
|
const requiredImports = new Set();
|
|
48
45
|
for (const param of params) {
|
|
@@ -91,10 +88,10 @@ const makeKeyframedOptions = ({ param, remotionLocalNames, }) => {
|
|
|
91
88
|
if (param.clamping.right !== 'extend') {
|
|
92
89
|
properties.push(b.objectProperty(b.identifier('extrapolateRight'), b.stringLiteral(param.clamping.right)));
|
|
93
90
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
91
|
+
}
|
|
92
|
+
if (keyframedParamNeedsEasingImport(param)) {
|
|
93
|
+
const easingLocalName = (_a = remotionLocalNames.Easing) !== null && _a !== void 0 ? _a : 'Easing';
|
|
94
|
+
properties.push(b.objectProperty(b.identifier('easing'), b.arrayExpression(param.easing.map((easing) => makeEasingExpression({ easing, easingLocalName })))));
|
|
98
95
|
}
|
|
99
96
|
if (param.posterize !== undefined) {
|
|
100
97
|
properties.push(b.objectProperty(b.identifier('posterize'), (0, update_nested_prop_1.parseValueExpression)(param.posterize)));
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type KeyframeInterpolationFunction } from '@remotion/studio-shared';
|
|
2
|
-
import type { ExtrapolateType, SequenceNodePath, SequenceSchema } from 'remotion';
|
|
2
|
+
import type { CanUpdateSequencePropStatus, ExtrapolateType, SequenceNodePath, SequenceSchema } from 'remotion';
|
|
3
|
+
type KeyframeEasing = Extract<CanUpdateSequencePropStatus, {
|
|
4
|
+
status: 'keyframed';
|
|
5
|
+
}>['easing'][number];
|
|
3
6
|
export type KeyframeOperation = {
|
|
4
7
|
type: 'add';
|
|
5
8
|
frame: number;
|
|
@@ -14,6 +17,10 @@ export type KeyframeOperation = {
|
|
|
14
17
|
right: ExtrapolateType;
|
|
15
18
|
} | undefined;
|
|
16
19
|
posterize: number | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'easing';
|
|
22
|
+
segmentIndex: number;
|
|
23
|
+
easing: KeyframeEasing;
|
|
17
24
|
} | {
|
|
18
25
|
type: 'move';
|
|
19
26
|
moves: {
|
|
@@ -32,6 +39,7 @@ export type EffectKeyframeUpdate = {
|
|
|
32
39
|
export type IntroducedKeyframeIdentifiers = {
|
|
33
40
|
calleeName: KeyframeInterpolationFunction | null;
|
|
34
41
|
needsFrameHook: boolean;
|
|
42
|
+
needsEasingImport: boolean;
|
|
35
43
|
};
|
|
36
44
|
export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, schema, }: {
|
|
37
45
|
input: string;
|
|
@@ -89,3 +97,4 @@ export declare const updateEffectKeyframes: ({ input, sequenceNodePath, effectIn
|
|
|
89
97
|
effectCallee: string;
|
|
90
98
|
updatedSequenceNodePath: SequenceNodePath;
|
|
91
99
|
}>;
|
|
100
|
+
export {};
|
|
@@ -44,6 +44,62 @@ const update_effect_props_1 = require("../update-effect-props/update-effect-prop
|
|
|
44
44
|
const update_nested_prop_1 = require("../update-nested-prop");
|
|
45
45
|
const ensure_imports_and_frame_hook_1 = require("./ensure-imports-and-frame-hook");
|
|
46
46
|
const b = recast.types.builders;
|
|
47
|
+
const getObjectPropertyNameFromUpdateKey = (key) => {
|
|
48
|
+
const dotIndex = key.indexOf('.');
|
|
49
|
+
return dotIndex === -1 ? key : key.slice(dotIndex + 1);
|
|
50
|
+
};
|
|
51
|
+
const lineStartsWithPropertyName = ({ line, propertyName, }) => {
|
|
52
|
+
const trimmed = line.trimStart();
|
|
53
|
+
return (trimmed.startsWith(`${propertyName}:`) ||
|
|
54
|
+
trimmed.startsWith(`'${propertyName}':`) ||
|
|
55
|
+
trimmed.startsWith(`"${propertyName}":`));
|
|
56
|
+
};
|
|
57
|
+
const getIndent = (line) => {
|
|
58
|
+
var _a;
|
|
59
|
+
var _b;
|
|
60
|
+
return (_b = (_a = line.match(/^[ \t]*/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '';
|
|
61
|
+
};
|
|
62
|
+
const removeBlankLinesFromObjectsWithProperties = ({ input, propertyNames, }) => {
|
|
63
|
+
if (propertyNames.length === 0) {
|
|
64
|
+
return input;
|
|
65
|
+
}
|
|
66
|
+
const lines = input.split('\n');
|
|
67
|
+
const linesToRemove = new Set();
|
|
68
|
+
for (let i = 0; i < lines.length; i++) {
|
|
69
|
+
const propertyName = propertyNames.find((name) => lineStartsWithPropertyName({ line: lines[i], propertyName: name }));
|
|
70
|
+
if (!propertyName) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const propertyIndentLength = getIndent(lines[i]).length;
|
|
74
|
+
let objectStart = i;
|
|
75
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
76
|
+
const trimmed = lines[j].trim();
|
|
77
|
+
if (trimmed.endsWith('{') &&
|
|
78
|
+
getIndent(lines[j]).length < propertyIndentLength) {
|
|
79
|
+
objectStart = j;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let objectEnd = i;
|
|
84
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
85
|
+
const trimmed = lines[j].trim();
|
|
86
|
+
if (trimmed.startsWith('}') &&
|
|
87
|
+
getIndent(lines[j]).length < propertyIndentLength) {
|
|
88
|
+
objectEnd = j;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (let j = objectStart + 1; j < objectEnd; j++) {
|
|
93
|
+
if (lines[j].trim() === '') {
|
|
94
|
+
linesToRemove.add(j);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (linesToRemove.size === 0) {
|
|
99
|
+
return input;
|
|
100
|
+
}
|
|
101
|
+
return lines.filter((_, index) => !linesToRemove.has(index)).join('\n');
|
|
102
|
+
};
|
|
47
103
|
const getSupportedCallArgument = (arg) => {
|
|
48
104
|
if (arg === undefined ||
|
|
49
105
|
arg.type === 'ArgumentPlaceholder' ||
|
|
@@ -168,6 +224,203 @@ const setOptionsProperty = ({ options, propertyName, value, }) => {
|
|
|
168
224
|
}
|
|
169
225
|
options.properties.push(b.objectProperty(b.identifier(propertyName), value));
|
|
170
226
|
};
|
|
227
|
+
const isLinearEasing = (easing) => easing === 'linear';
|
|
228
|
+
const getKeyframeEasing = (node) => {
|
|
229
|
+
if (node.type === 'TSAsExpression') {
|
|
230
|
+
return getKeyframeEasing(node.expression);
|
|
231
|
+
}
|
|
232
|
+
if (node.type === 'MemberExpression' &&
|
|
233
|
+
node.object.type === 'Identifier' &&
|
|
234
|
+
node.object.name === 'Easing' &&
|
|
235
|
+
node.property.type === 'Identifier' &&
|
|
236
|
+
node.property.name === 'linear' &&
|
|
237
|
+
node.computed === false) {
|
|
238
|
+
return 'linear';
|
|
239
|
+
}
|
|
240
|
+
if (node.type !== 'CallExpression' ||
|
|
241
|
+
node.callee.type !== 'MemberExpression' ||
|
|
242
|
+
node.callee.object.type !== 'Identifier' ||
|
|
243
|
+
node.callee.object.name !== 'Easing' ||
|
|
244
|
+
node.callee.property.type !== 'Identifier' ||
|
|
245
|
+
node.callee.property.name !== 'bezier' ||
|
|
246
|
+
node.callee.computed ||
|
|
247
|
+
node.arguments.length !== 4) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
const values = node.arguments.map((arg) => {
|
|
251
|
+
if (arg.type === 'ArgumentPlaceholder' ||
|
|
252
|
+
arg.type === 'JSXNamespacedName' ||
|
|
253
|
+
arg.type === 'SpreadElement') {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return getNumericValue(arg);
|
|
257
|
+
});
|
|
258
|
+
if (values.some((value) => value === null)) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
return values;
|
|
262
|
+
};
|
|
263
|
+
const getKeyframeEasingArray = ({ easingNode, segmentCount, }) => {
|
|
264
|
+
if (segmentCount === 0) {
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
if (easingNode.type === 'TSAsExpression') {
|
|
268
|
+
return getKeyframeEasingArray({
|
|
269
|
+
easingNode: easingNode.expression,
|
|
270
|
+
segmentCount,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (easingNode.type === 'ArrayExpression') {
|
|
274
|
+
if (easingNode.elements.length > segmentCount) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
const parsed = easingNode.elements.map((element) => {
|
|
278
|
+
if (!element || element.type === 'SpreadElement') {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
return getKeyframeEasing(element);
|
|
282
|
+
});
|
|
283
|
+
if (parsed.some((value) => value === null)) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
const easingArray = parsed;
|
|
287
|
+
while (easingArray.length < segmentCount) {
|
|
288
|
+
easingArray.push('linear');
|
|
289
|
+
}
|
|
290
|
+
return easingArray;
|
|
291
|
+
}
|
|
292
|
+
const easing = getKeyframeEasing(easingNode);
|
|
293
|
+
if (!easing) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
return new Array(segmentCount).fill(easing);
|
|
297
|
+
};
|
|
298
|
+
const getExistingEasingArray = ({ options, segmentCount, }) => {
|
|
299
|
+
const { prop } = findObjectOptionProperty(options, 'easing');
|
|
300
|
+
if (!prop) {
|
|
301
|
+
return new Array(segmentCount).fill('linear');
|
|
302
|
+
}
|
|
303
|
+
const easing = getKeyframeEasingArray({
|
|
304
|
+
easingNode: prop.value,
|
|
305
|
+
segmentCount,
|
|
306
|
+
});
|
|
307
|
+
if (!easing) {
|
|
308
|
+
throw new Error('Cannot update easing: easing must be inline');
|
|
309
|
+
}
|
|
310
|
+
return easing;
|
|
311
|
+
};
|
|
312
|
+
const getExistingEasingArrayOrNull = ({ options, segmentCount, }) => {
|
|
313
|
+
const { prop } = findObjectOptionProperty(options, 'easing');
|
|
314
|
+
if (!prop) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
return getExistingEasingArray({ options, segmentCount });
|
|
318
|
+
};
|
|
319
|
+
const createEasingExpression = (easing) => {
|
|
320
|
+
if (easing === 'linear') {
|
|
321
|
+
return b.memberExpression(b.identifier('Easing'), b.identifier('linear'));
|
|
322
|
+
}
|
|
323
|
+
return b.callExpression(b.memberExpression(b.identifier('Easing'), b.identifier('bezier')), easing.map((value) => (0, update_nested_prop_1.parseValueExpression)(value)));
|
|
324
|
+
};
|
|
325
|
+
const createEasingArrayExpression = (easing) => b.arrayExpression(easing.map((easingValue) => createEasingExpression(easingValue)));
|
|
326
|
+
const setEasingOption = ({ options, easing, }) => {
|
|
327
|
+
const hasNonLinearEasing = easing.some((easingValue) => !isLinearEasing(easingValue));
|
|
328
|
+
setOptionsProperty({
|
|
329
|
+
options,
|
|
330
|
+
propertyName: 'easing',
|
|
331
|
+
value: hasNonLinearEasing ? createEasingArrayExpression(easing) : null,
|
|
332
|
+
});
|
|
333
|
+
return hasNonLinearEasing;
|
|
334
|
+
};
|
|
335
|
+
const getExtraArgsWithOptions = ({ extraArgs, options, }) => {
|
|
336
|
+
return options.properties.length === 0
|
|
337
|
+
? extraArgs.slice(1)
|
|
338
|
+
: [options, ...extraArgs.slice(1)];
|
|
339
|
+
};
|
|
340
|
+
const getInlineOptionsFromExtraArgs = (extraArgs) => {
|
|
341
|
+
const existingOptions = extraArgs[0];
|
|
342
|
+
if (!existingOptions || existingOptions.type !== 'ObjectExpression') {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
return existingOptions;
|
|
346
|
+
};
|
|
347
|
+
const normalizeEasingAfterAddingKeyframe = ({ extraArgs, previousSegmentCount, nextSegmentCount, }) => {
|
|
348
|
+
const options = getInlineOptionsFromExtraArgs(extraArgs);
|
|
349
|
+
if (!options) {
|
|
350
|
+
return { extraArgs, needsEasingImport: false };
|
|
351
|
+
}
|
|
352
|
+
const easing = getExistingEasingArrayOrNull({
|
|
353
|
+
options,
|
|
354
|
+
segmentCount: previousSegmentCount,
|
|
355
|
+
});
|
|
356
|
+
if (easing === null) {
|
|
357
|
+
return { extraArgs, needsEasingImport: false };
|
|
358
|
+
}
|
|
359
|
+
while (easing.length < nextSegmentCount) {
|
|
360
|
+
easing.push('linear');
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
|
|
364
|
+
needsEasingImport: setEasingOption({ options, easing }),
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
const normalizeEasingAfterRemovingKeyframe = ({ extraArgs, previousSegmentCount, nextSegmentCount, removedKeyframeIndex, }) => {
|
|
368
|
+
const options = getInlineOptionsFromExtraArgs(extraArgs);
|
|
369
|
+
if (!options) {
|
|
370
|
+
return { extraArgs, needsEasingImport: false };
|
|
371
|
+
}
|
|
372
|
+
const easing = getExistingEasingArrayOrNull({
|
|
373
|
+
options,
|
|
374
|
+
segmentCount: previousSegmentCount,
|
|
375
|
+
});
|
|
376
|
+
if (easing === null) {
|
|
377
|
+
return { extraArgs, needsEasingImport: false };
|
|
378
|
+
}
|
|
379
|
+
if (easing.length > 0) {
|
|
380
|
+
const easingIndexToRemove = removedKeyframeIndex === 0 ? 0 : removedKeyframeIndex - 1;
|
|
381
|
+
easing.splice(easingIndexToRemove, 1);
|
|
382
|
+
}
|
|
383
|
+
while (easing.length > nextSegmentCount) {
|
|
384
|
+
easing.pop();
|
|
385
|
+
}
|
|
386
|
+
while (easing.length < nextSegmentCount) {
|
|
387
|
+
easing.push('linear');
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
|
|
391
|
+
needsEasingImport: setEasingOption({ options, easing }),
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
const normalizeEasingAfterRemovingKeyframes = ({ extraArgs, previousSegmentCount, nextSegmentCount, removedKeyframeIndexes, }) => {
|
|
395
|
+
const options = getInlineOptionsFromExtraArgs(extraArgs);
|
|
396
|
+
if (!options) {
|
|
397
|
+
return { extraArgs, needsEasingImport: false };
|
|
398
|
+
}
|
|
399
|
+
const easing = getExistingEasingArrayOrNull({
|
|
400
|
+
options,
|
|
401
|
+
segmentCount: previousSegmentCount,
|
|
402
|
+
});
|
|
403
|
+
if (easing === null) {
|
|
404
|
+
return { extraArgs, needsEasingImport: false };
|
|
405
|
+
}
|
|
406
|
+
for (const removedKeyframeIndex of [...removedKeyframeIndexes].sort((first, second) => second - first)) {
|
|
407
|
+
if (easing.length === 0) {
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
const easingIndexToRemove = removedKeyframeIndex === 0 ? 0 : removedKeyframeIndex - 1;
|
|
411
|
+
easing.splice(easingIndexToRemove, 1);
|
|
412
|
+
}
|
|
413
|
+
while (easing.length > nextSegmentCount) {
|
|
414
|
+
easing.pop();
|
|
415
|
+
}
|
|
416
|
+
while (easing.length < nextSegmentCount) {
|
|
417
|
+
easing.push('linear');
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
|
|
421
|
+
needsEasingImport: setEasingOption({ options, easing }),
|
|
422
|
+
};
|
|
423
|
+
};
|
|
171
424
|
const validatePosterize = (posterize) => {
|
|
172
425
|
if (posterize === undefined) {
|
|
173
426
|
return;
|
|
@@ -227,6 +480,46 @@ const updateKeyframeSettings = ({ expression, clamping, posterize, }) => {
|
|
|
227
480
|
keyframes: existing.keyframes,
|
|
228
481
|
});
|
|
229
482
|
};
|
|
483
|
+
const updateKeyframeEasing = ({ expression, segmentIndex, easing, }) => {
|
|
484
|
+
const existing = getInterpolationExpression(expression);
|
|
485
|
+
if (!existing) {
|
|
486
|
+
throw new Error('Cannot update easing on non-keyframed value');
|
|
487
|
+
}
|
|
488
|
+
const segmentCount = Math.max(0, existing.keyframes.length - 1);
|
|
489
|
+
if (!Number.isInteger(segmentIndex) ||
|
|
490
|
+
segmentIndex < 0 ||
|
|
491
|
+
segmentIndex >= segmentCount) {
|
|
492
|
+
throw new Error('Cannot update easing: segment index out of range');
|
|
493
|
+
}
|
|
494
|
+
const extraArgs = [...existing.extraArgs];
|
|
495
|
+
const existingOptions = extraArgs[0];
|
|
496
|
+
if (existingOptions && existingOptions.type !== 'ObjectExpression') {
|
|
497
|
+
throw new Error('Cannot update easing: options must be inline');
|
|
498
|
+
}
|
|
499
|
+
const options = (existingOptions === null || existingOptions === void 0 ? void 0 : existingOptions.type) === 'ObjectExpression'
|
|
500
|
+
? existingOptions
|
|
501
|
+
: createEmptyOptionsExpression();
|
|
502
|
+
const nextEasing = getExistingEasingArray({ options, segmentCount });
|
|
503
|
+
nextEasing[segmentIndex] = easing;
|
|
504
|
+
const hasNonLinearEasing = nextEasing.some((easingValue) => !isLinearEasing(easingValue));
|
|
505
|
+
setOptionsProperty({
|
|
506
|
+
options,
|
|
507
|
+
propertyName: 'easing',
|
|
508
|
+
value: hasNonLinearEasing ? createEasingArrayExpression(nextEasing) : null,
|
|
509
|
+
});
|
|
510
|
+
const nextExtraArgs = options.properties.length === 0
|
|
511
|
+
? extraArgs.slice(1)
|
|
512
|
+
: [options, ...extraArgs.slice(1)];
|
|
513
|
+
return {
|
|
514
|
+
expression: createInterpolateExpression({
|
|
515
|
+
callee: existing.callee,
|
|
516
|
+
input: existing.input,
|
|
517
|
+
extraArgs: nextExtraArgs,
|
|
518
|
+
keyframes: existing.keyframes,
|
|
519
|
+
}),
|
|
520
|
+
needsEasingImport: hasNonLinearEasing,
|
|
521
|
+
};
|
|
522
|
+
};
|
|
230
523
|
const createInterpolateExpression = ({ callee, input, extraArgs, keyframes, }) => {
|
|
231
524
|
const sortedKeyframes = [...keyframes].sort((first, second) => first.frame - second.frame);
|
|
232
525
|
return b.callExpression(callee, [
|
|
@@ -239,6 +532,7 @@ const createInterpolateExpression = ({ callee, input, extraArgs, keyframes, }) =
|
|
|
239
532
|
const noIntroducedIdentifiers = {
|
|
240
533
|
calleeName: null,
|
|
241
534
|
needsFrameHook: false,
|
|
535
|
+
needsEasingImport: false,
|
|
242
536
|
};
|
|
243
537
|
const addKeyframe = ({ expression, key, frame, value, schema, }) => {
|
|
244
538
|
if (!(0, studio_shared_1.isSchemaFieldKeyframable)({ schema, key })) {
|
|
@@ -261,11 +555,18 @@ const addKeyframe = ({ expression, key, frame, value, schema, }) => {
|
|
|
261
555
|
: existing.keyframes.map((keyframe, index) => index === existingIndex
|
|
262
556
|
? { frame, output: newOutput, value }
|
|
263
557
|
: keyframe);
|
|
558
|
+
const normalizedEasing = existingIndex === -1
|
|
559
|
+
? normalizeEasingAfterAddingKeyframe({
|
|
560
|
+
extraArgs: existing.extraArgs,
|
|
561
|
+
previousSegmentCount: Math.max(existing.keyframes.length - 1, 0),
|
|
562
|
+
nextSegmentCount: Math.max(nextKeyframes.length - 1, 0),
|
|
563
|
+
})
|
|
564
|
+
: { extraArgs: existing.extraArgs, needsEasingImport: false };
|
|
264
565
|
return {
|
|
265
566
|
expression: createInterpolateExpression({
|
|
266
567
|
callee: b.identifier(nextCalleeName),
|
|
267
568
|
input: existing.input,
|
|
268
|
-
extraArgs:
|
|
569
|
+
extraArgs: normalizedEasing.extraArgs,
|
|
269
570
|
keyframes: nextKeyframes,
|
|
270
571
|
}),
|
|
271
572
|
introduced: {
|
|
@@ -273,6 +574,7 @@ const addKeyframe = ({ expression, key, frame, value, schema, }) => {
|
|
|
273
574
|
? schemaCalleeName
|
|
274
575
|
: null,
|
|
275
576
|
needsFrameHook: false,
|
|
577
|
+
needsEasingImport: normalizedEasing.needsEasingImport,
|
|
276
578
|
},
|
|
277
579
|
};
|
|
278
580
|
}
|
|
@@ -302,6 +604,7 @@ const addKeyframe = ({ expression, key, frame, value, schema, }) => {
|
|
|
302
604
|
? callee.name
|
|
303
605
|
: null,
|
|
304
606
|
needsFrameHook: true,
|
|
607
|
+
needsEasingImport: false,
|
|
305
608
|
},
|
|
306
609
|
};
|
|
307
610
|
};
|
|
@@ -316,17 +619,31 @@ const removeKeyframe = ({ expression, frame, }) => {
|
|
|
316
619
|
}
|
|
317
620
|
const nextKeyframes = existing.keyframes.filter((_keyframe, index) => index !== keyframeIndex);
|
|
318
621
|
if (nextKeyframes.length === 0) {
|
|
319
|
-
return
|
|
622
|
+
return {
|
|
623
|
+
expression: existing.keyframes[keyframeIndex].output,
|
|
624
|
+
introduced: noIntroducedIdentifiers,
|
|
625
|
+
};
|
|
320
626
|
}
|
|
321
|
-
|
|
322
|
-
callee: existing.callee,
|
|
323
|
-
input: existing.input,
|
|
627
|
+
const normalizedEasing = normalizeEasingAfterRemovingKeyframe({
|
|
324
628
|
extraArgs: existing.extraArgs,
|
|
325
|
-
|
|
629
|
+
previousSegmentCount: Math.max(existing.keyframes.length - 1, 0),
|
|
630
|
+
nextSegmentCount: Math.max(nextKeyframes.length - 1, 0),
|
|
631
|
+
removedKeyframeIndex: keyframeIndex,
|
|
326
632
|
});
|
|
633
|
+
return {
|
|
634
|
+
expression: createInterpolateExpression({
|
|
635
|
+
callee: existing.callee,
|
|
636
|
+
input: existing.input,
|
|
637
|
+
extraArgs: normalizedEasing.extraArgs,
|
|
638
|
+
keyframes: nextKeyframes,
|
|
639
|
+
}),
|
|
640
|
+
introduced: {
|
|
641
|
+
...noIntroducedIdentifiers,
|
|
642
|
+
needsEasingImport: normalizedEasing.needsEasingImport,
|
|
643
|
+
},
|
|
644
|
+
};
|
|
327
645
|
};
|
|
328
646
|
const moveKeyframes = ({ expression, moves, }) => {
|
|
329
|
-
var _a;
|
|
330
647
|
const existing = getInterpolationExpression(expression);
|
|
331
648
|
if (!existing) {
|
|
332
649
|
throw new Error('Cannot move keyframe in non-interpolated expression');
|
|
@@ -351,28 +668,38 @@ const moveKeyframes = ({ expression, moves, }) => {
|
|
|
351
668
|
}
|
|
352
669
|
}
|
|
353
670
|
const movedFromFrames = new Set(moveMap.keys());
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
671
|
+
const movedToFrames = new Set(moveMap.values());
|
|
672
|
+
const removedKeyframeIndexes = [];
|
|
673
|
+
const nextKeyframes = existing.keyframes.flatMap((keyframe, index) => {
|
|
674
|
+
const movedFrame = moveMap.get(keyframe.frame);
|
|
675
|
+
if (movedFrame !== undefined) {
|
|
676
|
+
return [{ ...keyframe, frame: movedFrame }];
|
|
359
677
|
}
|
|
360
|
-
if (
|
|
361
|
-
|
|
678
|
+
if (movedToFrames.has(keyframe.frame) &&
|
|
679
|
+
!movedFromFrames.has(keyframe.frame)) {
|
|
680
|
+
removedKeyframeIndexes.push(index);
|
|
681
|
+
return [];
|
|
682
|
+
}
|
|
683
|
+
return [keyframe];
|
|
684
|
+
});
|
|
685
|
+
const nextFrames = new Set();
|
|
686
|
+
for (const keyframe of nextKeyframes) {
|
|
687
|
+
if (nextFrames.has(keyframe.frame)) {
|
|
688
|
+
throw new Error(`Cannot move keyframe to frame ${keyframe.frame}: frame already exists`);
|
|
362
689
|
}
|
|
363
|
-
nextFrames.add(
|
|
690
|
+
nextFrames.add(keyframe.frame);
|
|
364
691
|
}
|
|
692
|
+
const normalizedEasing = normalizeEasingAfterRemovingKeyframes({
|
|
693
|
+
extraArgs: existing.extraArgs,
|
|
694
|
+
previousSegmentCount: Math.max(existing.keyframes.length - 1, 0),
|
|
695
|
+
nextSegmentCount: Math.max(nextKeyframes.length - 1, 0),
|
|
696
|
+
removedKeyframeIndexes,
|
|
697
|
+
});
|
|
365
698
|
return createInterpolateExpression({
|
|
366
699
|
callee: existing.callee,
|
|
367
700
|
input: existing.input,
|
|
368
|
-
extraArgs:
|
|
369
|
-
keyframes:
|
|
370
|
-
var _a;
|
|
371
|
-
return ({
|
|
372
|
-
...keyframe,
|
|
373
|
-
frame: (_a = moveMap.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame,
|
|
374
|
-
});
|
|
375
|
-
}),
|
|
701
|
+
extraArgs: normalizedEasing.extraArgs,
|
|
702
|
+
keyframes: nextKeyframes,
|
|
376
703
|
});
|
|
377
704
|
};
|
|
378
705
|
const applyKeyframeOperation = ({ expression, key, operation, schema, }) => {
|
|
@@ -395,16 +722,27 @@ const applyKeyframeOperation = ({ expression, key, operation, schema, }) => {
|
|
|
395
722
|
introduced: noIntroducedIdentifiers,
|
|
396
723
|
};
|
|
397
724
|
}
|
|
725
|
+
if (operation.type === 'easing') {
|
|
726
|
+
const updated = updateKeyframeEasing({
|
|
727
|
+
expression,
|
|
728
|
+
segmentIndex: operation.segmentIndex,
|
|
729
|
+
easing: operation.easing,
|
|
730
|
+
});
|
|
731
|
+
return {
|
|
732
|
+
expression: updated.expression,
|
|
733
|
+
introduced: {
|
|
734
|
+
...noIntroducedIdentifiers,
|
|
735
|
+
needsEasingImport: updated.needsEasingImport,
|
|
736
|
+
},
|
|
737
|
+
};
|
|
738
|
+
}
|
|
398
739
|
if (operation.type === 'move') {
|
|
399
740
|
return {
|
|
400
741
|
expression: moveKeyframes({ expression, moves: operation.moves }),
|
|
401
742
|
introduced: noIntroducedIdentifiers,
|
|
402
743
|
};
|
|
403
744
|
}
|
|
404
|
-
return {
|
|
405
|
-
expression: removeKeyframe({ expression, frame: operation.frame }),
|
|
406
|
-
introduced: noIntroducedIdentifiers,
|
|
407
|
-
};
|
|
745
|
+
return removeKeyframe({ expression, frame: operation.frame });
|
|
408
746
|
};
|
|
409
747
|
const getExpressionFromJsxAttribute = (attr) => {
|
|
410
748
|
if (!attr.value) {
|
|
@@ -609,6 +947,9 @@ const updateSequenceKeyframesAst = ({ input, nodePath, updates, schema, }) => {
|
|
|
609
947
|
requiredImports.add('useCurrentFrame');
|
|
610
948
|
needsFrameHook = true;
|
|
611
949
|
}
|
|
950
|
+
if (introduced.needsEasingImport) {
|
|
951
|
+
requiredImports.add('Easing');
|
|
952
|
+
}
|
|
612
953
|
}
|
|
613
954
|
if (needsFrameHook) {
|
|
614
955
|
const fnPath = (0, ensure_imports_and_frame_hook_1.findEnclosingFunctionPath)(jsxPath);
|
|
@@ -641,8 +982,12 @@ const updateSequenceKeyframes = async ({ input, nodePath, updates, schema, prett
|
|
|
641
982
|
input: serialized,
|
|
642
983
|
prettierConfigOverride,
|
|
643
984
|
});
|
|
985
|
+
const outputWithoutInsertedBlankLines = removeBlankLinesFromObjectsWithProperties({
|
|
986
|
+
input: output,
|
|
987
|
+
propertyNames: updates.map((update) => getObjectPropertyNameFromUpdateKey(update.key)),
|
|
988
|
+
});
|
|
644
989
|
return {
|
|
645
|
-
output,
|
|
990
|
+
output: outputWithoutInsertedBlankLines,
|
|
646
991
|
formatted,
|
|
647
992
|
oldValueStrings,
|
|
648
993
|
newValueStrings,
|
|
@@ -699,6 +1044,9 @@ const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, update
|
|
|
699
1044
|
requiredImports.add('useCurrentFrame');
|
|
700
1045
|
needsFrameHook = true;
|
|
701
1046
|
}
|
|
1047
|
+
if (introduced.needsEasingImport) {
|
|
1048
|
+
requiredImports.add('Easing');
|
|
1049
|
+
}
|
|
702
1050
|
}
|
|
703
1051
|
if (needsFrameHook) {
|
|
704
1052
|
const fnPath = (0, ensure_imports_and_frame_hook_1.findEnclosingFunctionPath)(jsxPath);
|
|
@@ -733,8 +1081,12 @@ const updateEffectKeyframes = async ({ input, sequenceNodePath, effectIndex, upd
|
|
|
733
1081
|
input: serialized,
|
|
734
1082
|
prettierConfigOverride,
|
|
735
1083
|
});
|
|
1084
|
+
const outputWithoutInsertedBlankLines = removeBlankLinesFromObjectsWithProperties({
|
|
1085
|
+
input: output,
|
|
1086
|
+
propertyNames: updates.map((update) => update.key),
|
|
1087
|
+
});
|
|
736
1088
|
return {
|
|
737
|
-
output,
|
|
1089
|
+
output: outputWithoutInsertedBlankLines,
|
|
738
1090
|
formatted,
|
|
739
1091
|
oldValueStrings,
|
|
740
1092
|
newValueStrings,
|
package/dist/helpers/imports.js
CHANGED
|
@@ -105,18 +105,23 @@ const ensureNamedImport = ({ ast, importedName, sourcePath, localName, }) => {
|
|
|
105
105
|
};
|
|
106
106
|
exports.ensureNamedImport = ensureNamedImport;
|
|
107
107
|
const ensureNamedImports = ({ ast, importedNames, sourcePath, }) => {
|
|
108
|
-
var _a
|
|
108
|
+
var _a;
|
|
109
|
+
var _b, _c, _d;
|
|
109
110
|
if (importedNames.size === 0) {
|
|
110
111
|
return;
|
|
111
112
|
}
|
|
112
113
|
const existingImports = findImportDeclarations(ast, sourcePath);
|
|
113
114
|
const existingNames = new Set();
|
|
114
115
|
for (const existingImportDeclaration of existingImports) {
|
|
115
|
-
for (const importSpecifierCandidate of (
|
|
116
|
+
for (const importSpecifierCandidate of (_b = existingImportDeclaration.specifiers) !== null && _b !== void 0 ? _b : []) {
|
|
116
117
|
if (importSpecifierCandidate.type !== 'ImportSpecifier') {
|
|
117
118
|
continue;
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
+
const importedName = (0, exports.getImportedName)(importSpecifierCandidate);
|
|
121
|
+
const localName = (_c = (_a = importSpecifierCandidate.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _c !== void 0 ? _c : importedName;
|
|
122
|
+
if (localName === importedName) {
|
|
123
|
+
existingNames.add(importedName);
|
|
124
|
+
}
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
const existingImport = existingImports.find((candidateImportDeclaration) => !hasNamespaceSpecifier(candidateImportDeclaration));
|
|
@@ -126,7 +131,7 @@ const ensureNamedImports = ({ ast, importedNames, sourcePath, }) => {
|
|
|
126
131
|
continue;
|
|
127
132
|
}
|
|
128
133
|
existingImport.specifiers = [
|
|
129
|
-
...((
|
|
134
|
+
...((_d = existingImport.specifiers) !== null && _d !== void 0 ? _d : []),
|
|
130
135
|
b.importSpecifier(b.identifier(importedName)),
|
|
131
136
|
];
|
|
132
137
|
existingNames.add(importedName);
|
|
@@ -548,12 +548,12 @@ const createComponentElement = ({ localName, props, }) => {
|
|
|
548
548
|
createPositionAbsoluteStyleAttribute(),
|
|
549
549
|
], true), null, []);
|
|
550
550
|
};
|
|
551
|
-
const createAssetElement = ({ localName, staticFileLocalName, src, dimensions, }) => {
|
|
551
|
+
const createAssetElement = ({ addPositionStyle, localName, staticFileLocalName, src, dimensions, }) => {
|
|
552
552
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
553
553
|
staticFileLocalName === null
|
|
554
554
|
? createStringSrcAttribute(src)
|
|
555
555
|
: createStaticFileSrcAttribute({ staticFileLocalName, src }),
|
|
556
|
-
createPositionAbsoluteStyleAttribute(),
|
|
556
|
+
...(addPositionStyle ? [createPositionAbsoluteStyleAttribute()] : []),
|
|
557
557
|
...(dimensions
|
|
558
558
|
? [
|
|
559
559
|
createNumberAttribute('width', dimensions.width),
|
|
@@ -1043,6 +1043,7 @@ const createInsertableJsxElement = ({ ast, element, }) => {
|
|
|
1043
1043
|
throw new Error('Unsupported asset type');
|
|
1044
1044
|
}
|
|
1045
1045
|
return createAssetElement({
|
|
1046
|
+
addPositionStyle: element.assetType !== 'audio',
|
|
1046
1047
|
localName,
|
|
1047
1048
|
staticFileLocalName,
|
|
1048
1049
|
src: element.src,
|