@remotion/studio-server 4.0.468 → 4.0.470
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/delete-effect.d.ts +18 -0
- package/dist/codemods/delete-effect.js +95 -21
- package/dist/codemods/delete-jsx-node.d.ts +10 -0
- package/dist/codemods/delete-jsx-node.js +38 -14
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +4 -0
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +152 -0
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +8 -0
- package/dist/codemods/update-keyframes/update-keyframes.js +98 -31
- package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +32 -10
- package/dist/codemods/update-sequence-props/update-sequence-props.js +39 -7
- package/dist/index.d.ts +2 -1
- package/dist/preview-server/api-routes.js +16 -0
- package/dist/preview-server/routes/add-effect-keyframe.d.ts +3 -0
- package/dist/preview-server/routes/add-effect-keyframe.js +91 -0
- package/dist/preview-server/routes/add-sequence-keyframe.d.ts +3 -0
- package/dist/preview-server/routes/add-sequence-keyframe.js +84 -0
- package/dist/preview-server/routes/apply-codemod.js +1 -0
- package/dist/preview-server/routes/apply-visual-control-change.js +1 -0
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +0 -9
- package/dist/preview-server/routes/can-update-sequence-props.js +192 -24
- package/dist/preview-server/routes/composition-component-info.d.ts +3 -0
- package/dist/preview-server/routes/composition-component-info.js +26 -0
- package/dist/preview-server/routes/delete-effect-keyframe.d.ts +3 -0
- package/dist/preview-server/routes/delete-effect-keyframe.js +89 -0
- package/dist/preview-server/routes/delete-effect.js +76 -37
- package/dist/preview-server/routes/delete-jsx-node.js +67 -36
- package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +3 -0
- package/dist/preview-server/routes/delete-sequence-keyframe.js +82 -0
- package/dist/preview-server/routes/duplicate-jsx-node.js +1 -0
- package/dist/preview-server/routes/open-in-editor.d.ts +4 -0
- package/dist/preview-server/routes/open-in-editor.js +40 -0
- package/dist/preview-server/routes/register-client-render.d.ts +3 -0
- package/dist/preview-server/routes/register-client-render.js +11 -0
- package/dist/preview-server/routes/save-effect-props.js +1 -0
- package/dist/preview-server/routes/save-sequence-props.js +161 -72
- package/dist/preview-server/routes/unregister-client-render.d.ts +4 -0
- package/dist/preview-server/routes/unregister-client-render.js +11 -0
- package/dist/preview-server/routes/update-default-props.js +1 -0
- package/dist/preview-server/start-server.d.ts +1 -0
- package/dist/preview-server/start-server.js +1 -0
- package/dist/preview-server/undo-stack.d.ts +26 -3
- package/dist/preview-server/undo-stack.js +130 -42
- package/dist/preview-server/validate-same-origin.d.ts +2 -0
- package/dist/preview-server/validate-same-origin.js +13 -0
- package/dist/routes.d.ts +2 -1
- package/dist/routes.js +9 -136
- package/dist/start-studio.d.ts +2 -1
- package/dist/start-studio.js +2 -1
- package/package.json +6 -6
|
@@ -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;
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
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;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
38
|
const renderer_1 = require("@remotion/renderer");
|
|
39
39
|
const recast = __importStar(require("recast"));
|
|
@@ -128,6 +128,174 @@ const getNumericValue = (node) => {
|
|
|
128
128
|
}
|
|
129
129
|
return null;
|
|
130
130
|
};
|
|
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) => {
|
|
147
|
+
if (node.type === 'TSAsExpression') {
|
|
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 = (interpolationFunction, callExpression, keyframeCount) => {
|
|
215
|
+
const segments = Math.max(0, keyframeCount - 1);
|
|
216
|
+
const defaultClamping = interpolationFunction === 'interpolateColors'
|
|
217
|
+
? {
|
|
218
|
+
left: 'clamp',
|
|
219
|
+
right: 'clamp',
|
|
220
|
+
}
|
|
221
|
+
: {
|
|
222
|
+
left: 'extend',
|
|
223
|
+
right: 'extend',
|
|
224
|
+
};
|
|
225
|
+
const defaults = {
|
|
226
|
+
easing: new Array(segments).fill('linear'),
|
|
227
|
+
clamping: defaultClamping,
|
|
228
|
+
posterize: undefined,
|
|
229
|
+
};
|
|
230
|
+
const optionsArg = callExpression.arguments[3];
|
|
231
|
+
if (!optionsArg) {
|
|
232
|
+
return defaults;
|
|
233
|
+
}
|
|
234
|
+
if (optionsArg.type !== 'ObjectExpression') {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
let { easing } = defaults;
|
|
238
|
+
let { clamping } = defaults;
|
|
239
|
+
let posterize;
|
|
240
|
+
for (const property of optionsArg.properties) {
|
|
241
|
+
if (property.type !== 'ObjectProperty' || property.computed) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const key = property.key.type === 'Identifier'
|
|
245
|
+
? property.key.name
|
|
246
|
+
: property.key.type === 'StringLiteral'
|
|
247
|
+
? property.key.value
|
|
248
|
+
: null;
|
|
249
|
+
if (!key) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
const value = property.value;
|
|
253
|
+
if (key === 'easing') {
|
|
254
|
+
if (interpolationFunction === 'interpolateColors') {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
const parsedEasing = getKeyframeEasingArray({
|
|
258
|
+
easingNode: value,
|
|
259
|
+
segments,
|
|
260
|
+
});
|
|
261
|
+
if (!parsedEasing) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
easing = parsedEasing;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (key === 'extrapolateLeft' || key === 'extrapolateRight') {
|
|
268
|
+
if (interpolationFunction === 'interpolateColors') {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const extrapolateType = getExtrapolateType(value);
|
|
272
|
+
if (!extrapolateType) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
clamping =
|
|
276
|
+
key === 'extrapolateLeft'
|
|
277
|
+
? { ...clamping, left: extrapolateType }
|
|
278
|
+
: { ...clamping, right: extrapolateType };
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (key === 'posterize') {
|
|
282
|
+
const parsedPosterize = getNumericValue(value);
|
|
283
|
+
if (parsedPosterize === null ||
|
|
284
|
+
!Number.isFinite(parsedPosterize) ||
|
|
285
|
+
parsedPosterize <= 0) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
posterize = parsedPosterize;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
easing,
|
|
295
|
+
clamping,
|
|
296
|
+
posterize,
|
|
297
|
+
};
|
|
298
|
+
};
|
|
131
299
|
const getInterpolationKeyframes = (node) => {
|
|
132
300
|
if (node.type === 'TSAsExpression') {
|
|
133
301
|
return getInterpolationKeyframes(node.expression);
|
|
@@ -141,6 +309,7 @@ const getInterpolationKeyframes = (node) => {
|
|
|
141
309
|
callExpression.callee.name !== 'interpolateColors')) {
|
|
142
310
|
return undefined;
|
|
143
311
|
}
|
|
312
|
+
const interpolationFunction = callExpression.callee.name;
|
|
144
313
|
const inputArg = callExpression.arguments[1];
|
|
145
314
|
const outputArg = callExpression.arguments[2];
|
|
146
315
|
if (!inputArg ||
|
|
@@ -171,17 +340,34 @@ const getInterpolationKeyframes = (node) => {
|
|
|
171
340
|
value: (0, exports.extractStaticValue)(outputElement),
|
|
172
341
|
});
|
|
173
342
|
}
|
|
174
|
-
|
|
343
|
+
if (keyframes.length === 0) {
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
const metadata = getInterpolationMetadata(interpolationFunction, callExpression, keyframes.length);
|
|
347
|
+
if (!metadata) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
return {
|
|
351
|
+
interpolationFunction,
|
|
352
|
+
keyframes,
|
|
353
|
+
easing: metadata.easing,
|
|
354
|
+
clamping: metadata.clamping,
|
|
355
|
+
posterize: metadata.posterize,
|
|
356
|
+
};
|
|
175
357
|
};
|
|
176
358
|
const getComputedStatus = (node) => {
|
|
177
|
-
const
|
|
178
|
-
if (!
|
|
359
|
+
const interpolation = getInterpolationKeyframes(node);
|
|
360
|
+
if (!interpolation) {
|
|
179
361
|
return { canUpdate: false, reason: 'computed' };
|
|
180
362
|
}
|
|
181
363
|
return {
|
|
182
364
|
canUpdate: false,
|
|
183
|
-
reason: '
|
|
184
|
-
|
|
365
|
+
reason: 'keyframed',
|
|
366
|
+
interpolationFunction: interpolation.interpolationFunction,
|
|
367
|
+
keyframes: interpolation.keyframes,
|
|
368
|
+
easing: interpolation.easing,
|
|
369
|
+
clamping: interpolation.clamping,
|
|
370
|
+
posterize: interpolation.posterize,
|
|
185
371
|
};
|
|
186
372
|
};
|
|
187
373
|
exports.getComputedStatus = getComputedStatus;
|
|
@@ -345,24 +531,6 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, keys, }) => {
|
|
|
345
531
|
}
|
|
346
532
|
return filteredProps;
|
|
347
533
|
};
|
|
348
|
-
const computeSequencePropsOnlyStatus = ({ fileName, nodePath, keys, remotionRoot, }) => {
|
|
349
|
-
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
350
|
-
remotionRoot,
|
|
351
|
-
fileName,
|
|
352
|
-
action: 'read',
|
|
353
|
-
});
|
|
354
|
-
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
355
|
-
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
356
|
-
const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
|
|
357
|
-
if (!jsxElement) {
|
|
358
|
-
throw new Error('Cannot compute sequence props: Could not find a JSX element at the specified location');
|
|
359
|
-
}
|
|
360
|
-
return {
|
|
361
|
-
canUpdate: true,
|
|
362
|
-
props: computeSequenceOnlyPropsRecord({ jsxElement, keys }),
|
|
363
|
-
};
|
|
364
|
-
};
|
|
365
|
-
exports.computeSequencePropsOnlyStatus = computeSequencePropsOnlyStatus;
|
|
366
534
|
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, effects, }) => {
|
|
367
535
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
368
536
|
const jsxElement = (0, exports.findJsxElementAtNodePath)(ast, nodePath);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CompositionComponentInfoRequest, CompositionComponentInfoResponse } from '@remotion/studio-shared';
|
|
2
|
+
import type { ApiHandler } from '../api-types';
|
|
3
|
+
export declare const compositionComponentInfoHandler: ApiHandler<CompositionComponentInfoRequest, CompositionComponentInfoResponse>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compositionComponentInfoHandler = void 0;
|
|
4
|
+
const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
|
|
5
|
+
const compositionComponentInfoHandler = async ({ input: { compositionFile, compositionId }, remotionRoot }) => {
|
|
6
|
+
if (typeof compositionFile !== 'string') {
|
|
7
|
+
throw new TypeError('Need to pass compositionFile');
|
|
8
|
+
}
|
|
9
|
+
if (typeof compositionId !== 'string') {
|
|
10
|
+
throw new TypeError('Need to pass compositionId');
|
|
11
|
+
}
|
|
12
|
+
const location = await (0, resolve_composition_component_1.resolveCompositionComponent)({
|
|
13
|
+
remotionRoot,
|
|
14
|
+
compositionFile,
|
|
15
|
+
compositionId,
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
location: {
|
|
19
|
+
source: location.source,
|
|
20
|
+
line: location.line,
|
|
21
|
+
column: location.column,
|
|
22
|
+
},
|
|
23
|
+
canAddSequence: location.canAddSequence,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.compositionComponentInfoHandler = compositionComponentInfoHandler;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse } from '@remotion/studio-shared';
|
|
2
|
+
import type { ApiHandler } from '../api-types';
|
|
3
|
+
export declare const deleteEffectKeyframeHandler: ApiHandler<DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteEffectKeyframeHandler = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const renderer_1 = require("@remotion/renderer");
|
|
6
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
7
|
+
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
8
|
+
const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
|
|
9
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
10
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
11
|
+
const undo_stack_1 = require("../undo-stack");
|
|
12
|
+
const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
|
|
13
|
+
const can_update_effect_props_1 = require("./can-update-effect-props");
|
|
14
|
+
const can_update_sequence_props_1 = require("./can-update-sequence-props");
|
|
15
|
+
const log_effect_update_1 = require("./log-updates/log-effect-update");
|
|
16
|
+
const save_props_mutex_1 = require("./save-props-mutex");
|
|
17
|
+
const deleteEffectKeyframeHandler = ({ input: { fileName, sequenceNodePath, effectIndex, key, frame, schema, clientId, }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
|
|
18
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-effect-keyframe] Received request for fileName="${fileName}" effectIndex=${effectIndex} key="${key}" frame=${frame}`);
|
|
19
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
20
|
+
remotionRoot,
|
|
21
|
+
fileName,
|
|
22
|
+
action: 'modify',
|
|
23
|
+
});
|
|
24
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
25
|
+
const { output, oldValueStrings, newValueStrings, formatted, logLine, effectCallee, } = await (0, update_keyframes_1.updateEffectKeyframes)({
|
|
26
|
+
input: fileContents,
|
|
27
|
+
sequenceNodePath: sequenceNodePath.nodePath,
|
|
28
|
+
effectIndex,
|
|
29
|
+
updates: [
|
|
30
|
+
{
|
|
31
|
+
key,
|
|
32
|
+
operation: {
|
|
33
|
+
type: 'remove',
|
|
34
|
+
frame,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
const oldValueString = oldValueStrings[0];
|
|
40
|
+
const newValueString = newValueStrings[0];
|
|
41
|
+
const undoPropChange = `${key} keyframe restored at frame ${frame}`;
|
|
42
|
+
const redoPropChange = `${key} keyframe deleted at frame ${frame}`;
|
|
43
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
44
|
+
filePath: absolutePath,
|
|
45
|
+
oldContents: fileContents,
|
|
46
|
+
newContents: null,
|
|
47
|
+
logLevel,
|
|
48
|
+
remotionRoot,
|
|
49
|
+
logLine,
|
|
50
|
+
description: {
|
|
51
|
+
undoMessage: `↩️ ${undoPropChange}`,
|
|
52
|
+
redoMessage: `↪️ ${redoPropChange}`,
|
|
53
|
+
},
|
|
54
|
+
entryType: 'effect-props',
|
|
55
|
+
suppressHmrOnFileRestore: true,
|
|
56
|
+
});
|
|
57
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
|
|
58
|
+
(0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
|
|
59
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
|
|
60
|
+
(0, log_effect_update_1.logEffectUpdate)({
|
|
61
|
+
fileRelativeToRoot,
|
|
62
|
+
line: logLine,
|
|
63
|
+
effectName: effectCallee,
|
|
64
|
+
propKey: key,
|
|
65
|
+
oldValueString,
|
|
66
|
+
newValueString,
|
|
67
|
+
defaultValueString: null,
|
|
68
|
+
formatted,
|
|
69
|
+
logLevel,
|
|
70
|
+
removedProps: [],
|
|
71
|
+
addedProps: [],
|
|
72
|
+
});
|
|
73
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
74
|
+
const ast = (0, parse_ast_1.parseAst)((0, node_fs_1.readFileSync)(absolutePath, 'utf-8'));
|
|
75
|
+
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath.nodePath);
|
|
76
|
+
if (!jsx) {
|
|
77
|
+
return {
|
|
78
|
+
canUpdate: false,
|
|
79
|
+
effectIndex,
|
|
80
|
+
reason: 'not-found',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return (0, can_update_effect_props_1.computeEffectPropStatus)({
|
|
84
|
+
jsx,
|
|
85
|
+
effectIndex,
|
|
86
|
+
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
exports.deleteEffectKeyframeHandler = deleteEffectKeyframeHandler;
|
|
@@ -10,45 +10,84 @@ const format_log_file_location_1 = require("../format-log-file-location");
|
|
|
10
10
|
const undo_stack_1 = require("../undo-stack");
|
|
11
11
|
const formatting_1 = require("./log-updates/formatting");
|
|
12
12
|
const log_update_1 = require("./log-updates/log-update");
|
|
13
|
-
const
|
|
13
|
+
const getDeletedEffectDescription = (effectLabels) => {
|
|
14
|
+
if (effectLabels.length === 1) {
|
|
15
|
+
return effectLabels[0];
|
|
16
|
+
}
|
|
17
|
+
return `${effectLabels.length} effects`;
|
|
18
|
+
};
|
|
19
|
+
const deleteEffectHandler = async ({ input: effects, remotionRoot, logLevel }) => {
|
|
20
|
+
var _a;
|
|
14
21
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
22
|
+
if (effects.length === 0) {
|
|
23
|
+
throw new Error('No effects were specified for deletion');
|
|
24
|
+
}
|
|
25
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-effect] Received request to delete ${effects.length} effect target${effects.length === 1 ? '' : 's'}`);
|
|
26
|
+
const itemsByFileName = new Map();
|
|
27
|
+
for (const item of effects) {
|
|
28
|
+
const fileItems = (_a = itemsByFileName.get(item.fileName)) !== null && _a !== void 0 ? _a : [];
|
|
29
|
+
fileItems.push(item);
|
|
30
|
+
itemsByFileName.set(item.fileName, fileItems);
|
|
31
|
+
}
|
|
32
|
+
const updates = await Promise.all([...itemsByFileName.entries()].map(async ([fileName, fileItems]) => {
|
|
33
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
34
|
+
remotionRoot,
|
|
35
|
+
fileName,
|
|
36
|
+
action: 'modify',
|
|
37
|
+
});
|
|
38
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
39
|
+
const { output, formatted, effectLabels, logLines } = await (0, delete_effect_1.deleteEffects)({
|
|
40
|
+
input: fileContents,
|
|
41
|
+
effects: fileItems.map((item) => item.type === 'single-effect'
|
|
42
|
+
? {
|
|
43
|
+
type: 'single-effect',
|
|
44
|
+
sequenceNodePath: item.sequenceNodePath.nodePath,
|
|
45
|
+
effectIndex: item.effectIndex,
|
|
46
|
+
}
|
|
47
|
+
: {
|
|
48
|
+
type: 'all-effects',
|
|
49
|
+
sequenceNodePath: item.sequenceNodePath.nodePath,
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
absolutePath,
|
|
54
|
+
fileRelativeToRoot,
|
|
55
|
+
fileContents,
|
|
56
|
+
output,
|
|
57
|
+
formatted,
|
|
58
|
+
effectLabels,
|
|
59
|
+
logLine: Math.min(...logLines),
|
|
60
|
+
};
|
|
61
|
+
}));
|
|
62
|
+
for (const update of updates) {
|
|
63
|
+
const deletedEffectDescription = getDeletedEffectDescription(update.effectLabels);
|
|
64
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
65
|
+
filePath: update.absolutePath,
|
|
66
|
+
oldContents: update.fileContents,
|
|
67
|
+
newContents: null,
|
|
68
|
+
logLevel,
|
|
69
|
+
remotionRoot,
|
|
70
|
+
logLine: update.logLine,
|
|
71
|
+
description: {
|
|
72
|
+
undoMessage: `↩️ Deletion of ${deletedEffectDescription}`,
|
|
73
|
+
redoMessage: `↪️ Deletion of ${deletedEffectDescription}`,
|
|
74
|
+
},
|
|
75
|
+
entryType: 'delete-effect',
|
|
76
|
+
suppressHmrOnFileRestore: false,
|
|
77
|
+
});
|
|
78
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(update.absolutePath);
|
|
79
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(update.absolutePath, update.output, undefined);
|
|
80
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
81
|
+
remotionRoot,
|
|
82
|
+
absolutePath: update.absolutePath,
|
|
83
|
+
line: update.logLine,
|
|
84
|
+
});
|
|
85
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} ${(0, formatting_1.strikeThroughOrRemovedPrefix)(deletedEffectDescription)}`);
|
|
86
|
+
if (!update.formatted) {
|
|
87
|
+
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
88
|
+
}
|
|
89
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[delete-effect] Wrote ${update.fileRelativeToRoot}${update.formatted ? ' (formatted)' : ''}`);
|
|
50
90
|
}
|
|
51
|
-
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[delete-effect] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
|
|
52
91
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
53
92
|
return {
|
|
54
93
|
success: true,
|
|
@@ -9,44 +9,75 @@ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside
|
|
|
9
9
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
10
10
|
const undo_stack_1 = require("../undo-stack");
|
|
11
11
|
const log_update_1 = require("./log-updates/log-update");
|
|
12
|
-
const
|
|
12
|
+
const getDeletedNodeDescription = (nodeLabels) => {
|
|
13
|
+
if (nodeLabels.length === 1) {
|
|
14
|
+
return nodeLabels[0];
|
|
15
|
+
}
|
|
16
|
+
return `${nodeLabels.length} JSX nodes`;
|
|
17
|
+
};
|
|
18
|
+
const deleteJsxNodeHandler = async ({ input: { nodes }, remotionRoot, logLevel }) => {
|
|
19
|
+
var _a;
|
|
13
20
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
(0,
|
|
21
|
+
if (nodes.length === 0) {
|
|
22
|
+
throw new Error('No JSX nodes were specified for deletion');
|
|
23
|
+
}
|
|
24
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-jsx-node] Received request to delete ${nodes.length} JSX node${nodes.length === 1 ? '' : 's'}`);
|
|
25
|
+
const itemsByFileName = new Map();
|
|
26
|
+
for (const item of nodes) {
|
|
27
|
+
const fileItems = (_a = itemsByFileName.get(item.fileName)) !== null && _a !== void 0 ? _a : [];
|
|
28
|
+
fileItems.push(item);
|
|
29
|
+
itemsByFileName.set(item.fileName, fileItems);
|
|
30
|
+
}
|
|
31
|
+
const updates = await Promise.all([...itemsByFileName.entries()].map(async ([fileName, fileItems]) => {
|
|
32
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
33
|
+
remotionRoot,
|
|
34
|
+
fileName,
|
|
35
|
+
action: 'modify',
|
|
36
|
+
});
|
|
37
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
38
|
+
const { output, formatted, nodeLabels, logLines } = await (0, delete_jsx_node_1.deleteJsxNodes)({
|
|
39
|
+
input: fileContents,
|
|
40
|
+
nodePaths: fileItems.map((item) => item.nodePath),
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
absolutePath,
|
|
44
|
+
fileRelativeToRoot,
|
|
45
|
+
fileContents,
|
|
46
|
+
output,
|
|
47
|
+
formatted,
|
|
48
|
+
nodeLabels,
|
|
49
|
+
logLine: Math.min(...logLines),
|
|
50
|
+
};
|
|
51
|
+
}));
|
|
52
|
+
for (const update of updates) {
|
|
53
|
+
const deletedNodeDescription = getDeletedNodeDescription(update.nodeLabels);
|
|
54
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
55
|
+
filePath: update.absolutePath,
|
|
56
|
+
oldContents: update.fileContents,
|
|
57
|
+
newContents: null,
|
|
58
|
+
logLevel,
|
|
59
|
+
remotionRoot,
|
|
60
|
+
logLine: update.logLine,
|
|
61
|
+
description: {
|
|
62
|
+
undoMessage: `↩️ Deletion of ${deletedNodeDescription}`,
|
|
63
|
+
redoMessage: `↪️ Deletion of ${deletedNodeDescription}`,
|
|
64
|
+
},
|
|
65
|
+
entryType: 'delete-jsx-node',
|
|
66
|
+
suppressHmrOnFileRestore: false,
|
|
67
|
+
});
|
|
68
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(update.absolutePath);
|
|
69
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(update.absolutePath, update.output, undefined);
|
|
70
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
71
|
+
remotionRoot,
|
|
72
|
+
absolutePath: update.absolutePath,
|
|
73
|
+
line: update.logLine,
|
|
74
|
+
});
|
|
75
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Deleted ${deletedNodeDescription}`);
|
|
76
|
+
if (!update.formatted) {
|
|
77
|
+
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
78
|
+
}
|
|
79
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[delete-jsx-node] Wrote ${update.fileRelativeToRoot}${update.formatted ? ' (formatted)' : ''}`);
|
|
48
80
|
}
|
|
49
|
-
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[delete-jsx-node] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
|
|
50
81
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
51
82
|
return {
|
|
52
83
|
success: true,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse } from '@remotion/studio-shared';
|
|
2
|
+
import type { ApiHandler } from '../api-types';
|
|
3
|
+
export declare const deleteSequenceKeyframeHandler: ApiHandler<DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse>;
|