@remotion/studio-server 4.0.471 → 4.0.473
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/add-effect.d.ts +11 -0
- package/dist/codemods/add-effect.js +14 -52
- package/dist/codemods/effect-param-expression.d.ts +15 -0
- package/dist/codemods/effect-param-expression.js +131 -0
- package/dist/codemods/format-file-content.js +1 -1
- package/dist/codemods/parse-ast.js +4 -1
- package/dist/codemods/paste-effects.d.ts +15 -0
- package/dist/codemods/paste-effects.js +147 -0
- package/dist/codemods/recast-mods.js +178 -31
- package/dist/codemods/reorder-sequence.d.ts +14 -0
- package/dist/codemods/reorder-sequence.js +109 -0
- package/dist/codemods/update-effect-props/update-effect-props.d.ts +7 -0
- package/dist/codemods/update-effect-props/update-effect-props.js +64 -16
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +1 -1
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +7 -55
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +24 -6
- package/dist/codemods/update-keyframes/update-keyframes.js +279 -16
- package/dist/helpers/get-ast-node-path.js +6 -1
- package/dist/helpers/import-agnostic-node-path.d.ts +10 -0
- package/dist/helpers/import-agnostic-node-path.js +154 -0
- package/dist/helpers/imports.d.ts +16 -0
- package/dist/helpers/imports.js +145 -0
- package/dist/helpers/resolve-composition-component.js +133 -51
- package/dist/preview-server/api-routes.js +16 -0
- package/dist/preview-server/routes/add-effect-keyframe.js +2 -0
- package/dist/preview-server/routes/add-sequence-keyframe.js +1 -0
- package/dist/preview-server/routes/apply-codemod.js +18 -0
- package/dist/preview-server/routes/can-update-effect-props.d.ts +3 -2
- package/dist/preview-server/routes/can-update-effect-props.js +78 -8
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +1 -1
- package/dist/preview-server/routes/can-update-sequence-props.js +82 -43
- package/dist/preview-server/routes/delete-keyframes.js +1 -0
- package/dist/preview-server/routes/download-remote-asset.d.ts +7 -0
- package/dist/preview-server/routes/download-remote-asset.js +267 -0
- package/dist/preview-server/routes/insert-jsx-element.js +26 -0
- package/dist/preview-server/routes/log-studio-error.d.ts +3 -0
- package/dist/preview-server/routes/log-studio-error.js +58 -0
- package/dist/preview-server/routes/move-keyframes.d.ts +7 -0
- package/dist/preview-server/routes/move-keyframes.js +242 -0
- package/dist/preview-server/routes/paste-effects.d.ts +3 -0
- package/dist/preview-server/routes/paste-effects.js +78 -0
- package/dist/preview-server/routes/rename-static-file.d.ts +3 -0
- package/dist/preview-server/routes/rename-static-file.js +53 -0
- package/dist/preview-server/routes/reorder-sequence.d.ts +3 -0
- package/dist/preview-server/routes/reorder-sequence.js +67 -0
- package/dist/preview-server/routes/save-effect-props.js +25 -9
- package/dist/preview-server/routes/save-sequence-props.js +2 -34
- package/dist/preview-server/routes/update-effect-keyframe-settings.d.ts +3 -0
- package/dist/preview-server/routes/update-effect-keyframe-settings.js +90 -0
- package/dist/preview-server/routes/update-sequence-keyframe-settings.d.ts +3 -0
- package/dist/preview-server/routes/update-sequence-keyframe-settings.js +85 -0
- package/dist/preview-server/undo-stack.d.ts +9 -1
- package/package.json +6 -6
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.ensureUseCurrentFrameHook = exports.ensureRemotionImports = exports.findEnclosingFunctionPath = void 0;
|
|
37
37
|
const recast = __importStar(require("recast"));
|
|
38
|
+
const imports_1 = require("../../helpers/imports");
|
|
38
39
|
const b = recast.types.builders;
|
|
39
40
|
const n = recast.types.namedTypes;
|
|
40
41
|
const isFunctionNode = (value) => {
|
|
@@ -53,60 +54,11 @@ const findEnclosingFunctionPath = (path) => {
|
|
|
53
54
|
return null;
|
|
54
55
|
};
|
|
55
56
|
exports.findEnclosingFunctionPath = findEnclosingFunctionPath;
|
|
56
|
-
const findRemotionImport = (ast) => {
|
|
57
|
-
for (const stmt of ast.program.body) {
|
|
58
|
-
if (stmt.type === 'ImportDeclaration' &&
|
|
59
|
-
stmt.source.type === 'StringLiteral' &&
|
|
60
|
-
stmt.source.value === 'remotion') {
|
|
61
|
-
return stmt;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
};
|
|
66
|
-
const insertImportDeclaration = (ast, importDecl) => {
|
|
67
|
-
const { body } = ast.program;
|
|
68
|
-
let lastImportIndex = -1;
|
|
69
|
-
for (let i = 0; i < body.length; i++) {
|
|
70
|
-
if (body[i].type === 'ImportDeclaration') {
|
|
71
|
-
lastImportIndex = i;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
body.splice(lastImportIndex + 1, 0, importDecl);
|
|
75
|
-
};
|
|
76
57
|
const ensureRemotionImports = (ast, names) => {
|
|
77
|
-
|
|
78
|
-
if (names.size === 0) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
let remotionImport = findRemotionImport(ast);
|
|
82
|
-
if (!remotionImport) {
|
|
83
|
-
remotionImport = b.importDeclaration([], b.stringLiteral('remotion'));
|
|
84
|
-
insertImportDeclaration(ast, remotionImport);
|
|
85
|
-
}
|
|
86
|
-
const existingNames = new Set();
|
|
87
|
-
for (const specifier of (_a = remotionImport.specifiers) !== null && _a !== void 0 ? _a : []) {
|
|
88
|
-
if (specifier.type !== 'ImportSpecifier') {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const { imported } = specifier;
|
|
92
|
-
if (imported.type === 'Identifier') {
|
|
93
|
-
existingNames.add(imported.name);
|
|
94
|
-
}
|
|
95
|
-
else if (imported.type === 'StringLiteral') {
|
|
96
|
-
existingNames.add(imported.value);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
for (const name of names) {
|
|
100
|
-
if (existingNames.has(name)) {
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
remotionImport.specifiers = (_b = remotionImport.specifiers) !== null && _b !== void 0 ? _b : [];
|
|
104
|
-
remotionImport.specifiers.push(b.importSpecifier(b.identifier(name)));
|
|
105
|
-
existingNames.add(name);
|
|
106
|
-
}
|
|
58
|
+
(0, imports_1.ensureNamedImports)({ ast, importedNames: names, sourcePath: 'remotion' });
|
|
107
59
|
};
|
|
108
60
|
exports.ensureRemotionImports = ensureRemotionImports;
|
|
109
|
-
const componentBodyHasFrameDeclaration = (body) => {
|
|
61
|
+
const componentBodyHasFrameDeclaration = ({ body, hookName, }) => {
|
|
110
62
|
if (!n.BlockStatement.check(body)) {
|
|
111
63
|
return false;
|
|
112
64
|
}
|
|
@@ -123,14 +75,14 @@ const componentBodyHasFrameDeclaration = (body) => {
|
|
|
123
75
|
decl.init &&
|
|
124
76
|
decl.init.type === 'CallExpression' &&
|
|
125
77
|
decl.init.callee.type === 'Identifier' &&
|
|
126
|
-
decl.init.callee.name ===
|
|
78
|
+
decl.init.callee.name === hookName) {
|
|
127
79
|
return true;
|
|
128
80
|
}
|
|
129
81
|
}
|
|
130
82
|
}
|
|
131
83
|
return false;
|
|
132
84
|
};
|
|
133
|
-
const ensureUseCurrentFrameHook = (functionPath) => {
|
|
85
|
+
const ensureUseCurrentFrameHook = (functionPath, hookName = 'useCurrentFrame') => {
|
|
134
86
|
const fn = functionPath.value;
|
|
135
87
|
if (!n.BlockStatement.check(fn.body)) {
|
|
136
88
|
// Arrow function with expression body: wrap the expression in a block so
|
|
@@ -140,12 +92,12 @@ const ensureUseCurrentFrameHook = (functionPath) => {
|
|
|
140
92
|
b.returnStatement(expression),
|
|
141
93
|
]);
|
|
142
94
|
}
|
|
143
|
-
if (componentBodyHasFrameDeclaration(fn.body)) {
|
|
95
|
+
if (componentBodyHasFrameDeclaration({ body: fn.body, hookName })) {
|
|
144
96
|
return;
|
|
145
97
|
}
|
|
146
98
|
const block = fn.body;
|
|
147
99
|
const frameDecl = b.variableDeclaration('const', [
|
|
148
|
-
b.variableDeclarator(b.identifier('frame'), b.callExpression(b.identifier(
|
|
100
|
+
b.variableDeclarator(b.identifier('frame'), b.callExpression(b.identifier(hookName), [])),
|
|
149
101
|
]);
|
|
150
102
|
block.body.unshift(frameDecl);
|
|
151
103
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type KeyframeInterpolationFunction } from '@remotion/studio-shared';
|
|
2
|
+
import type { ExtrapolateType, SequenceNodePath, SequenceSchema } from 'remotion';
|
|
2
3
|
export type KeyframeOperation = {
|
|
3
4
|
type: 'add';
|
|
4
5
|
frame: number;
|
|
@@ -6,6 +7,19 @@ export type KeyframeOperation = {
|
|
|
6
7
|
} | {
|
|
7
8
|
type: 'remove';
|
|
8
9
|
frame: number;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'settings';
|
|
12
|
+
clamping: {
|
|
13
|
+
left: ExtrapolateType;
|
|
14
|
+
right: ExtrapolateType;
|
|
15
|
+
} | undefined;
|
|
16
|
+
posterize: number | undefined;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'move';
|
|
19
|
+
moves: {
|
|
20
|
+
fromFrame: number;
|
|
21
|
+
toFrame: number;
|
|
22
|
+
}[];
|
|
9
23
|
};
|
|
10
24
|
export type SequenceKeyframeUpdate = {
|
|
11
25
|
key: string;
|
|
@@ -16,13 +30,14 @@ export type EffectKeyframeUpdate = {
|
|
|
16
30
|
operation: KeyframeOperation;
|
|
17
31
|
};
|
|
18
32
|
export type IntroducedKeyframeIdentifiers = {
|
|
19
|
-
calleeName:
|
|
33
|
+
calleeName: KeyframeInterpolationFunction | null;
|
|
20
34
|
needsFrameHook: boolean;
|
|
21
35
|
};
|
|
22
|
-
export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, }: {
|
|
36
|
+
export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, schema, }: {
|
|
23
37
|
input: string;
|
|
24
38
|
nodePath: SequenceNodePath;
|
|
25
39
|
updates: SequenceKeyframeUpdate[];
|
|
40
|
+
schema?: SequenceSchema | undefined;
|
|
26
41
|
}) => {
|
|
27
42
|
serialized: string;
|
|
28
43
|
oldValueStrings: string[];
|
|
@@ -30,10 +45,11 @@ export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, }:
|
|
|
30
45
|
logLine: number;
|
|
31
46
|
updatedNodePath: SequenceNodePath;
|
|
32
47
|
};
|
|
33
|
-
export declare const updateSequenceKeyframes: ({ input, nodePath, updates, prettierConfigOverride, }: {
|
|
48
|
+
export declare const updateSequenceKeyframes: ({ input, nodePath, updates, schema, prettierConfigOverride, }: {
|
|
34
49
|
input: string;
|
|
35
50
|
nodePath: SequenceNodePath;
|
|
36
51
|
updates: SequenceKeyframeUpdate[];
|
|
52
|
+
schema?: SequenceSchema | undefined;
|
|
37
53
|
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
38
54
|
}) => Promise<{
|
|
39
55
|
output: string;
|
|
@@ -43,11 +59,12 @@ export declare const updateSequenceKeyframes: ({ input, nodePath, updates, prett
|
|
|
43
59
|
logLine: number;
|
|
44
60
|
updatedNodePath: SequenceNodePath;
|
|
45
61
|
}>;
|
|
46
|
-
export declare const updateEffectKeyframesAst: ({ input, sequenceNodePath, effectIndex, updates, }: {
|
|
62
|
+
export declare const updateEffectKeyframesAst: ({ input, sequenceNodePath, effectIndex, updates, schema, }: {
|
|
47
63
|
input: string;
|
|
48
64
|
sequenceNodePath: SequenceNodePath;
|
|
49
65
|
effectIndex: number;
|
|
50
66
|
updates: EffectKeyframeUpdate[];
|
|
67
|
+
schema?: SequenceSchema | undefined;
|
|
51
68
|
}) => {
|
|
52
69
|
serialized: string;
|
|
53
70
|
oldValueStrings: string[];
|
|
@@ -56,11 +73,12 @@ export declare const updateEffectKeyframesAst: ({ input, sequenceNodePath, effec
|
|
|
56
73
|
effectCallee: string;
|
|
57
74
|
updatedSequenceNodePath: SequenceNodePath;
|
|
58
75
|
};
|
|
59
|
-
export declare const updateEffectKeyframes: ({ input, sequenceNodePath, effectIndex, updates, prettierConfigOverride, }: {
|
|
76
|
+
export declare const updateEffectKeyframes: ({ input, sequenceNodePath, effectIndex, updates, schema, prettierConfigOverride, }: {
|
|
60
77
|
input: string;
|
|
61
78
|
sequenceNodePath: SequenceNodePath;
|
|
62
79
|
effectIndex: number;
|
|
63
80
|
updates: EffectKeyframeUpdate[];
|
|
81
|
+
schema?: SequenceSchema | undefined;
|
|
64
82
|
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
65
83
|
}) => Promise<{
|
|
66
84
|
output: string;
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.updateEffectKeyframes = exports.updateEffectKeyframesAst = exports.updateSequenceKeyframes = exports.updateSequenceKeyframesAst = void 0;
|
|
37
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
37
38
|
const recast = __importStar(require("recast"));
|
|
38
39
|
const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
|
|
39
40
|
const can_update_sequence_props_1 = require("../../preview-server/routes/can-update-sequence-props");
|
|
@@ -71,8 +72,7 @@ const getInterpolationExpression = (node) => {
|
|
|
71
72
|
}
|
|
72
73
|
if (node.type !== 'CallExpression' ||
|
|
73
74
|
node.callee.type !== 'Identifier' ||
|
|
74
|
-
(node.callee.name
|
|
75
|
-
node.callee.name !== 'interpolateColors')) {
|
|
75
|
+
!(0, studio_shared_1.isKeyframeInterpolationFunction)(node.callee.name)) {
|
|
76
76
|
return null;
|
|
77
77
|
}
|
|
78
78
|
const frameArg = getSupportedCallArgument(node.arguments[0]);
|
|
@@ -124,14 +124,109 @@ const getInterpolationExpression = (node) => {
|
|
|
124
124
|
keyframes,
|
|
125
125
|
};
|
|
126
126
|
};
|
|
127
|
-
const getInterpolationCalleeForValues = ({ staticValue, newValue, }) => {
|
|
128
|
-
return b.identifier(
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
const getInterpolationCalleeForValues = ({ schema, key, staticValue, newValue, }) => {
|
|
128
|
+
return b.identifier((0, studio_shared_1.getKeyframeInterpolationFunction)({
|
|
129
|
+
schema,
|
|
130
|
+
key,
|
|
131
|
+
staticValue,
|
|
132
|
+
newValue,
|
|
133
|
+
}));
|
|
131
134
|
};
|
|
132
135
|
const createFrameExpression = (frame) => {
|
|
133
136
|
return (0, update_nested_prop_1.parseValueExpression)(frame);
|
|
134
137
|
};
|
|
138
|
+
const createClampOptionsExpression = () => {
|
|
139
|
+
return b.objectExpression([
|
|
140
|
+
b.objectProperty(b.identifier('extrapolateLeft'), b.stringLiteral('clamp')),
|
|
141
|
+
b.objectProperty(b.identifier('extrapolateRight'), b.stringLiteral('clamp')),
|
|
142
|
+
]);
|
|
143
|
+
};
|
|
144
|
+
const createEmptyOptionsExpression = () => b.objectExpression([]);
|
|
145
|
+
const findObjectOptionProperty = (options, propertyName) => {
|
|
146
|
+
const propIndex = options.properties.findIndex((prop) => prop.type === 'ObjectProperty' &&
|
|
147
|
+
!prop.computed &&
|
|
148
|
+
((prop.key.type === 'Identifier' && prop.key.name === propertyName) ||
|
|
149
|
+
(prop.key.type === 'StringLiteral' && prop.key.value === propertyName)));
|
|
150
|
+
return {
|
|
151
|
+
propIndex,
|
|
152
|
+
prop: propIndex === -1
|
|
153
|
+
? undefined
|
|
154
|
+
: options.properties[propIndex],
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const setOptionsProperty = ({ options, propertyName, value, }) => {
|
|
158
|
+
const { propIndex, prop } = findObjectOptionProperty(options, propertyName);
|
|
159
|
+
if (value === null) {
|
|
160
|
+
if (propIndex !== -1) {
|
|
161
|
+
options.properties.splice(propIndex, 1);
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (prop) {
|
|
166
|
+
prop.value = value;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
options.properties.push(b.objectProperty(b.identifier(propertyName), value));
|
|
170
|
+
};
|
|
171
|
+
const validatePosterize = (posterize) => {
|
|
172
|
+
if (posterize === undefined) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!Number.isFinite(posterize) || posterize <= 0) {
|
|
176
|
+
throw new Error('Cannot update keyframe settings: posterize must be > 0');
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const updateKeyframeSettings = ({ expression, clamping, posterize, }) => {
|
|
180
|
+
validatePosterize(posterize);
|
|
181
|
+
const existing = getInterpolationExpression(expression);
|
|
182
|
+
if (!existing) {
|
|
183
|
+
throw new Error('Cannot update keyframe settings on non-keyframed value');
|
|
184
|
+
}
|
|
185
|
+
const calleeName = existing.callee.type === 'Identifier' ? existing.callee.name : null;
|
|
186
|
+
const isColorInterpolation = calleeName === 'interpolateColors';
|
|
187
|
+
const extraArgs = [...existing.extraArgs];
|
|
188
|
+
const existingOptions = extraArgs[0];
|
|
189
|
+
if (existingOptions && existingOptions.type !== 'ObjectExpression') {
|
|
190
|
+
throw new Error('Cannot update keyframe settings: options must be inline');
|
|
191
|
+
}
|
|
192
|
+
const options = (existingOptions === null || existingOptions === void 0 ? void 0 : existingOptions.type) === 'ObjectExpression'
|
|
193
|
+
? existingOptions
|
|
194
|
+
: createEmptyOptionsExpression();
|
|
195
|
+
if (isColorInterpolation) {
|
|
196
|
+
setOptionsProperty({ options, propertyName: 'extrapolateLeft', value: null });
|
|
197
|
+
setOptionsProperty({
|
|
198
|
+
options,
|
|
199
|
+
propertyName: 'extrapolateRight',
|
|
200
|
+
value: null,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else if (clamping) {
|
|
204
|
+
setOptionsProperty({
|
|
205
|
+
options,
|
|
206
|
+
propertyName: 'extrapolateLeft',
|
|
207
|
+
value: b.stringLiteral(clamping.left),
|
|
208
|
+
});
|
|
209
|
+
setOptionsProperty({
|
|
210
|
+
options,
|
|
211
|
+
propertyName: 'extrapolateRight',
|
|
212
|
+
value: b.stringLiteral(clamping.right),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
setOptionsProperty({
|
|
216
|
+
options,
|
|
217
|
+
propertyName: 'posterize',
|
|
218
|
+
value: posterize === undefined ? null : b.numericLiteral(posterize),
|
|
219
|
+
});
|
|
220
|
+
const nextExtraArgs = options.properties.length === 0
|
|
221
|
+
? extraArgs.slice(1)
|
|
222
|
+
: [options, ...extraArgs.slice(1)];
|
|
223
|
+
return createInterpolateExpression({
|
|
224
|
+
callee: existing.callee,
|
|
225
|
+
input: existing.input,
|
|
226
|
+
extraArgs: nextExtraArgs,
|
|
227
|
+
keyframes: existing.keyframes,
|
|
228
|
+
});
|
|
229
|
+
};
|
|
135
230
|
const createInterpolateExpression = ({ callee, input, extraArgs, keyframes, }) => {
|
|
136
231
|
const sortedKeyframes = [...keyframes].sort((first, second) => first.frame - second.frame);
|
|
137
232
|
return b.callExpression(callee, [
|
|
@@ -145,10 +240,21 @@ const noIntroducedIdentifiers = {
|
|
|
145
240
|
calleeName: null,
|
|
146
241
|
needsFrameHook: false,
|
|
147
242
|
};
|
|
148
|
-
const addKeyframe = ({ expression, frame, value, }) => {
|
|
243
|
+
const addKeyframe = ({ expression, key, frame, value, schema, }) => {
|
|
244
|
+
if (!(0, studio_shared_1.isSchemaFieldKeyframable)({ schema, key })) {
|
|
245
|
+
throw new Error(`Cannot add keyframe: "${key}" is not keyframable`);
|
|
246
|
+
}
|
|
149
247
|
const existing = getInterpolationExpression(expression);
|
|
150
248
|
const newOutput = (0, update_nested_prop_1.parseValueExpression)(value);
|
|
151
249
|
if (existing) {
|
|
250
|
+
const existingCalleeName = existing.callee.type === 'Identifier'
|
|
251
|
+
? existing.callee.name
|
|
252
|
+
: 'interpolate';
|
|
253
|
+
const schemaCalleeName = (0, studio_shared_1.getKeyframeInterpolationFunctionForSchemaField)({
|
|
254
|
+
schema,
|
|
255
|
+
key,
|
|
256
|
+
});
|
|
257
|
+
const nextCalleeName = schemaCalleeName !== null && schemaCalleeName !== void 0 ? schemaCalleeName : existingCalleeName;
|
|
152
258
|
const existingIndex = existing.keyframes.findIndex((keyframe) => keyframe.frame === frame);
|
|
153
259
|
const nextKeyframes = existingIndex === -1
|
|
154
260
|
? [...existing.keyframes, { frame, output: newOutput, value }]
|
|
@@ -157,12 +263,17 @@ const addKeyframe = ({ expression, frame, value, }) => {
|
|
|
157
263
|
: keyframe);
|
|
158
264
|
return {
|
|
159
265
|
expression: createInterpolateExpression({
|
|
160
|
-
callee:
|
|
266
|
+
callee: b.identifier(nextCalleeName),
|
|
161
267
|
input: existing.input,
|
|
162
268
|
extraArgs: existing.extraArgs,
|
|
163
269
|
keyframes: nextKeyframes,
|
|
164
270
|
}),
|
|
165
|
-
introduced:
|
|
271
|
+
introduced: {
|
|
272
|
+
calleeName: schemaCalleeName && schemaCalleeName !== existingCalleeName
|
|
273
|
+
? schemaCalleeName
|
|
274
|
+
: null,
|
|
275
|
+
needsFrameHook: false,
|
|
276
|
+
},
|
|
166
277
|
};
|
|
167
278
|
}
|
|
168
279
|
if (!(0, can_update_sequence_props_1.isStaticValue)(expression)) {
|
|
@@ -171,14 +282,19 @@ const addKeyframe = ({ expression, frame, value, }) => {
|
|
|
171
282
|
const staticValue = (0, can_update_sequence_props_1.extractStaticValue)(expression);
|
|
172
283
|
const keyframes = [{ frame, output: newOutput, value }];
|
|
173
284
|
const callee = getInterpolationCalleeForValues({
|
|
285
|
+
schema,
|
|
286
|
+
key,
|
|
174
287
|
staticValue,
|
|
175
288
|
newValue: value,
|
|
176
289
|
});
|
|
290
|
+
const extraArgs = callee.type === 'Identifier' && callee.name === 'interpolateColors'
|
|
291
|
+
? []
|
|
292
|
+
: [createClampOptionsExpression()];
|
|
177
293
|
return {
|
|
178
294
|
expression: createInterpolateExpression({
|
|
179
295
|
callee,
|
|
180
296
|
input: b.identifier('frame'),
|
|
181
|
-
extraArgs
|
|
297
|
+
extraArgs,
|
|
182
298
|
keyframes,
|
|
183
299
|
}),
|
|
184
300
|
introduced: {
|
|
@@ -209,14 +325,82 @@ const removeKeyframe = ({ expression, frame, }) => {
|
|
|
209
325
|
keyframes: nextKeyframes,
|
|
210
326
|
});
|
|
211
327
|
};
|
|
212
|
-
const
|
|
328
|
+
const moveKeyframes = ({ expression, moves, }) => {
|
|
329
|
+
var _a;
|
|
330
|
+
const existing = getInterpolationExpression(expression);
|
|
331
|
+
if (!existing) {
|
|
332
|
+
throw new Error('Cannot move keyframe in non-interpolated expression');
|
|
333
|
+
}
|
|
334
|
+
const moveMap = new Map();
|
|
335
|
+
for (const move of moves) {
|
|
336
|
+
if (move.fromFrame === move.toFrame) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (moveMap.has(move.fromFrame)) {
|
|
340
|
+
throw new Error(`Cannot move keyframe at frame ${move.fromFrame} twice`);
|
|
341
|
+
}
|
|
342
|
+
moveMap.set(move.fromFrame, move.toFrame);
|
|
343
|
+
}
|
|
344
|
+
if (moveMap.size === 0) {
|
|
345
|
+
return expression;
|
|
346
|
+
}
|
|
347
|
+
const frames = new Set(existing.keyframes.map((keyframe) => keyframe.frame));
|
|
348
|
+
for (const fromFrame of moveMap.keys()) {
|
|
349
|
+
if (!frames.has(fromFrame)) {
|
|
350
|
+
throw new Error(`Cannot move keyframe at frame ${fromFrame}: not found`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const movedFromFrames = new Set(moveMap.keys());
|
|
354
|
+
const nextFrames = new Set();
|
|
355
|
+
for (const keyframe of existing.keyframes) {
|
|
356
|
+
const nextFrame = (_a = moveMap.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame;
|
|
357
|
+
if (nextFrames.has(nextFrame)) {
|
|
358
|
+
throw new Error(`Cannot move keyframe to frame ${nextFrame}: frame already exists`);
|
|
359
|
+
}
|
|
360
|
+
if (!movedFromFrames.has(keyframe.frame) && moveMap.has(nextFrame)) {
|
|
361
|
+
throw new Error(`Cannot move keyframe to frame ${nextFrame}: frame already exists`);
|
|
362
|
+
}
|
|
363
|
+
nextFrames.add(nextFrame);
|
|
364
|
+
}
|
|
365
|
+
return createInterpolateExpression({
|
|
366
|
+
callee: existing.callee,
|
|
367
|
+
input: existing.input,
|
|
368
|
+
extraArgs: existing.extraArgs,
|
|
369
|
+
keyframes: existing.keyframes.map((keyframe) => {
|
|
370
|
+
var _a;
|
|
371
|
+
return ({
|
|
372
|
+
...keyframe,
|
|
373
|
+
frame: (_a = moveMap.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame,
|
|
374
|
+
});
|
|
375
|
+
}),
|
|
376
|
+
});
|
|
377
|
+
};
|
|
378
|
+
const applyKeyframeOperation = ({ expression, key, operation, schema, }) => {
|
|
213
379
|
if (operation.type === 'add') {
|
|
214
380
|
return addKeyframe({
|
|
215
381
|
expression,
|
|
382
|
+
key,
|
|
216
383
|
frame: operation.frame,
|
|
217
384
|
value: operation.value,
|
|
385
|
+
schema,
|
|
218
386
|
});
|
|
219
387
|
}
|
|
388
|
+
if (operation.type === 'settings') {
|
|
389
|
+
return {
|
|
390
|
+
expression: updateKeyframeSettings({
|
|
391
|
+
expression,
|
|
392
|
+
clamping: operation.clamping,
|
|
393
|
+
posterize: operation.posterize,
|
|
394
|
+
}),
|
|
395
|
+
introduced: noIntroducedIdentifiers,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
if (operation.type === 'move') {
|
|
399
|
+
return {
|
|
400
|
+
expression: moveKeyframes({ expression, moves: operation.moves }),
|
|
401
|
+
introduced: noIntroducedIdentifiers,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
220
404
|
return {
|
|
221
405
|
expression: removeKeyframe({ expression, frame: operation.frame }),
|
|
222
406
|
introduced: noIntroducedIdentifiers,
|
|
@@ -267,6 +451,30 @@ const findObjectProperty = (objExpr, propertyName) => {
|
|
|
267
451
|
: objExpr.properties[propIndex],
|
|
268
452
|
};
|
|
269
453
|
};
|
|
454
|
+
const findFieldInSchema = (schema, key) => {
|
|
455
|
+
if (key in schema) {
|
|
456
|
+
return schema[key];
|
|
457
|
+
}
|
|
458
|
+
for (const field of Object.values(schema)) {
|
|
459
|
+
if (field.type !== 'enum') {
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
for (const variant of Object.values(field.variants)) {
|
|
463
|
+
const found = findFieldInSchema(variant, key);
|
|
464
|
+
if (found) {
|
|
465
|
+
return found;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return undefined;
|
|
470
|
+
};
|
|
471
|
+
const getInitialValueForMissingProp = ({ schema, key, newValue, }) => {
|
|
472
|
+
const field = schema ? findFieldInSchema(schema, key) : undefined;
|
|
473
|
+
if (field && field.type !== 'hidden' && field.default !== undefined) {
|
|
474
|
+
return field.default;
|
|
475
|
+
}
|
|
476
|
+
return newValue;
|
|
477
|
+
};
|
|
270
478
|
const getObjectExpression = (attr) => {
|
|
271
479
|
if (!attr.value || attr.value.type !== 'JSXExpressionContainer') {
|
|
272
480
|
return null;
|
|
@@ -276,11 +484,31 @@ const getObjectExpression = (attr) => {
|
|
|
276
484
|
}
|
|
277
485
|
return attr.value.expression;
|
|
278
486
|
};
|
|
279
|
-
const
|
|
487
|
+
const createJsxExpressionAttribute = (key, expression) => {
|
|
488
|
+
return b.jsxAttribute(b.jsxIdentifier(key), b.jsxExpressionContainer(expression));
|
|
489
|
+
};
|
|
490
|
+
const createObjectProperty = (key, value) => b.objectProperty(b.identifier(key), value);
|
|
491
|
+
const createObjectExpressionAttribute = ({ parentKey, childKey, expression, }) => {
|
|
492
|
+
return createJsxExpressionAttribute(parentKey, b.objectExpression([
|
|
493
|
+
createObjectProperty(childKey, expression),
|
|
494
|
+
]));
|
|
495
|
+
};
|
|
496
|
+
const createMissingPropExpression = (missingPropInitialValue) => {
|
|
497
|
+
return (0, update_nested_prop_1.parseValueExpression)(missingPropInitialValue.value);
|
|
498
|
+
};
|
|
499
|
+
const getSequenceWritableProp = ({ attributes, key, missingPropInitialValue, }) => {
|
|
280
500
|
const dotIndex = key.indexOf('.');
|
|
281
501
|
if (dotIndex === -1) {
|
|
282
502
|
const { attr: topLevelAttr } = findJsxAttribute(attributes, key);
|
|
283
503
|
if (!topLevelAttr) {
|
|
504
|
+
if (missingPropInitialValue) {
|
|
505
|
+
return {
|
|
506
|
+
expression: createMissingPropExpression(missingPropInitialValue),
|
|
507
|
+
setExpression: (nextExpression) => {
|
|
508
|
+
attributes.push(createJsxExpressionAttribute(key, nextExpression));
|
|
509
|
+
},
|
|
510
|
+
};
|
|
511
|
+
}
|
|
284
512
|
throw new Error(`Cannot update keyframes: "${key}" is not set`);
|
|
285
513
|
}
|
|
286
514
|
const expression = getExpressionFromJsxAttribute(topLevelAttr);
|
|
@@ -298,6 +526,18 @@ const getSequenceWritableProp = ({ attributes, key, }) => {
|
|
|
298
526
|
const childKey = key.slice(dotIndex + 1);
|
|
299
527
|
const { attr: parentAttr } = findJsxAttribute(attributes, parentKey);
|
|
300
528
|
if (!parentAttr) {
|
|
529
|
+
if (missingPropInitialValue) {
|
|
530
|
+
return {
|
|
531
|
+
expression: createMissingPropExpression(missingPropInitialValue),
|
|
532
|
+
setExpression: (nextExpression) => {
|
|
533
|
+
attributes.push(createObjectExpressionAttribute({
|
|
534
|
+
parentKey,
|
|
535
|
+
childKey,
|
|
536
|
+
expression: nextExpression,
|
|
537
|
+
}));
|
|
538
|
+
},
|
|
539
|
+
};
|
|
540
|
+
}
|
|
301
541
|
throw new Error(`Cannot update keyframes: "${parentKey}" is not set`);
|
|
302
542
|
}
|
|
303
543
|
const objExpr = getObjectExpression(parentAttr);
|
|
@@ -306,6 +546,14 @@ const getSequenceWritableProp = ({ attributes, key, }) => {
|
|
|
306
546
|
}
|
|
307
547
|
const { prop } = findObjectProperty(objExpr, childKey);
|
|
308
548
|
if (!prop) {
|
|
549
|
+
if (missingPropInitialValue) {
|
|
550
|
+
return {
|
|
551
|
+
expression: createMissingPropExpression(missingPropInitialValue),
|
|
552
|
+
setExpression: (nextExpression) => {
|
|
553
|
+
objExpr.properties.push(createObjectProperty(childKey, nextExpression));
|
|
554
|
+
},
|
|
555
|
+
};
|
|
556
|
+
}
|
|
309
557
|
throw new Error(`Cannot update keyframes: "${key}" is not set`);
|
|
310
558
|
}
|
|
311
559
|
return {
|
|
@@ -315,7 +563,7 @@ const getSequenceWritableProp = ({ attributes, key, }) => {
|
|
|
315
563
|
},
|
|
316
564
|
};
|
|
317
565
|
};
|
|
318
|
-
const updateSequenceKeyframesAst = ({ input, nodePath, updates, }) => {
|
|
566
|
+
const updateSequenceKeyframesAst = ({ input, nodePath, updates, schema, }) => {
|
|
319
567
|
var _a;
|
|
320
568
|
var _b;
|
|
321
569
|
const ast = (0, parse_ast_1.parseAst)(input);
|
|
@@ -335,11 +583,22 @@ const updateSequenceKeyframesAst = ({ input, nodePath, updates, }) => {
|
|
|
335
583
|
const prop = getSequenceWritableProp({
|
|
336
584
|
attributes: node.attributes,
|
|
337
585
|
key: update.key,
|
|
586
|
+
missingPropInitialValue: update.operation.type === 'add'
|
|
587
|
+
? {
|
|
588
|
+
value: getInitialValueForMissingProp({
|
|
589
|
+
schema: schema !== null && schema !== void 0 ? schema : null,
|
|
590
|
+
key: update.key,
|
|
591
|
+
newValue: update.operation.value,
|
|
592
|
+
}),
|
|
593
|
+
}
|
|
594
|
+
: null,
|
|
338
595
|
});
|
|
339
596
|
oldValueStrings.push(recast.print(prop.expression).code);
|
|
340
597
|
const { expression: nextExpression, introduced } = applyKeyframeOperation({
|
|
341
598
|
expression: prop.expression,
|
|
599
|
+
key: update.key,
|
|
342
600
|
operation: update.operation,
|
|
601
|
+
schema: schema !== null && schema !== void 0 ? schema : null,
|
|
343
602
|
});
|
|
344
603
|
newValueStrings.push(recast.print(nextExpression).code);
|
|
345
604
|
prop.setExpression(nextExpression);
|
|
@@ -371,11 +630,12 @@ const updateSequenceKeyframesAst = ({ input, nodePath, updates, }) => {
|
|
|
371
630
|
};
|
|
372
631
|
};
|
|
373
632
|
exports.updateSequenceKeyframesAst = updateSequenceKeyframesAst;
|
|
374
|
-
const updateSequenceKeyframes = async ({ input, nodePath, updates, prettierConfigOverride, }) => {
|
|
633
|
+
const updateSequenceKeyframes = async ({ input, nodePath, updates, schema, prettierConfigOverride, }) => {
|
|
375
634
|
const { serialized, oldValueStrings, newValueStrings, logLine, updatedNodePath, } = (0, exports.updateSequenceKeyframesAst)({
|
|
376
635
|
input,
|
|
377
636
|
nodePath,
|
|
378
637
|
updates,
|
|
638
|
+
schema,
|
|
379
639
|
});
|
|
380
640
|
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
381
641
|
input: serialized,
|
|
@@ -391,7 +651,7 @@ const updateSequenceKeyframes = async ({ input, nodePath, updates, prettierConfi
|
|
|
391
651
|
};
|
|
392
652
|
};
|
|
393
653
|
exports.updateSequenceKeyframes = updateSequenceKeyframes;
|
|
394
|
-
const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, updates, }) => {
|
|
654
|
+
const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, updates, schema, }) => {
|
|
395
655
|
var _a, _b;
|
|
396
656
|
var _c, _d, _e;
|
|
397
657
|
const ast = (0, parse_ast_1.parseAst)(input);
|
|
@@ -426,7 +686,9 @@ const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, update
|
|
|
426
686
|
oldValueStrings.push(recast.print(prop.value).code);
|
|
427
687
|
const { expression: nextExpression, introduced } = applyKeyframeOperation({
|
|
428
688
|
expression: prop.value,
|
|
689
|
+
key: update.key,
|
|
429
690
|
operation: update.operation,
|
|
691
|
+
schema: schema !== null && schema !== void 0 ? schema : null,
|
|
430
692
|
});
|
|
431
693
|
newValueStrings.push(recast.print(nextExpression).code);
|
|
432
694
|
prop.value = nextExpression;
|
|
@@ -459,12 +721,13 @@ const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, update
|
|
|
459
721
|
};
|
|
460
722
|
};
|
|
461
723
|
exports.updateEffectKeyframesAst = updateEffectKeyframesAst;
|
|
462
|
-
const updateEffectKeyframes = async ({ input, sequenceNodePath, effectIndex, updates, prettierConfigOverride, }) => {
|
|
724
|
+
const updateEffectKeyframes = async ({ input, sequenceNodePath, effectIndex, updates, schema, prettierConfigOverride, }) => {
|
|
463
725
|
const { serialized, oldValueStrings, newValueStrings, logLine, effectCallee, updatedSequenceNodePath, } = (0, exports.updateEffectKeyframesAst)({
|
|
464
726
|
input,
|
|
465
727
|
sequenceNodePath,
|
|
466
728
|
effectIndex,
|
|
467
729
|
updates,
|
|
730
|
+
schema,
|
|
468
731
|
});
|
|
469
732
|
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
470
733
|
input: serialized,
|
|
@@ -35,9 +35,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.getAstNodePath = void 0;
|
|
37
37
|
const recast = __importStar(require("recast"));
|
|
38
|
+
const import_agnostic_node_path_1 = require("./import-agnostic-node-path");
|
|
38
39
|
const getAstNodePath = (ast, nodePath) => {
|
|
40
|
+
const resolvedNodePath = (0, import_agnostic_node_path_1.fromImportAgnosticNodePath)({ ast, nodePath });
|
|
41
|
+
if (!resolvedNodePath) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
39
44
|
let current = new recast.types.NodePath(ast);
|
|
40
|
-
for (const segment of
|
|
45
|
+
for (const segment of resolvedNodePath) {
|
|
41
46
|
current = current.get(segment);
|
|
42
47
|
if (current.value === null || current.value === undefined) {
|
|
43
48
|
return null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { File } from '@babel/types';
|
|
2
|
+
import type { SequenceNodePath } from 'remotion';
|
|
3
|
+
export declare const toImportAgnosticNodePath: ({ ast, nodePath, }: {
|
|
4
|
+
ast: File;
|
|
5
|
+
nodePath: SequenceNodePath;
|
|
6
|
+
}) => SequenceNodePath;
|
|
7
|
+
export declare const fromImportAgnosticNodePath: ({ ast, nodePath, }: {
|
|
8
|
+
ast: File;
|
|
9
|
+
nodePath: SequenceNodePath;
|
|
10
|
+
}) => SequenceNodePath | null;
|