@remotion/studio-server 4.0.469 → 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.
Files changed (48) hide show
  1. package/dist/codemods/delete-effect.d.ts +18 -0
  2. package/dist/codemods/delete-effect.js +95 -21
  3. package/dist/codemods/delete-jsx-node.d.ts +10 -0
  4. package/dist/codemods/delete-jsx-node.js +38 -14
  5. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +4 -0
  6. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +152 -0
  7. package/dist/codemods/update-keyframes/update-keyframes.d.ts +8 -0
  8. package/dist/codemods/update-keyframes/update-keyframes.js +94 -24
  9. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +32 -10
  10. package/dist/codemods/update-sequence-props/update-sequence-props.js +39 -7
  11. package/dist/index.d.ts +2 -1
  12. package/dist/preview-server/api-routes.js +16 -0
  13. package/dist/preview-server/routes/add-effect-keyframe.d.ts +3 -0
  14. package/dist/preview-server/routes/add-effect-keyframe.js +91 -0
  15. package/dist/preview-server/routes/add-sequence-keyframe.d.ts +3 -0
  16. package/dist/preview-server/routes/add-sequence-keyframe.js +84 -0
  17. package/dist/preview-server/routes/apply-codemod.js +1 -0
  18. package/dist/preview-server/routes/apply-visual-control-change.js +1 -0
  19. package/dist/preview-server/routes/can-update-sequence-props.js +33 -13
  20. package/dist/preview-server/routes/composition-component-info.d.ts +3 -0
  21. package/dist/preview-server/routes/composition-component-info.js +26 -0
  22. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +3 -0
  23. package/dist/preview-server/routes/delete-effect-keyframe.js +89 -0
  24. package/dist/preview-server/routes/delete-effect.js +76 -37
  25. package/dist/preview-server/routes/delete-jsx-node.js +67 -36
  26. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +3 -0
  27. package/dist/preview-server/routes/delete-sequence-keyframe.js +82 -0
  28. package/dist/preview-server/routes/duplicate-jsx-node.js +1 -0
  29. package/dist/preview-server/routes/open-in-editor.d.ts +4 -0
  30. package/dist/preview-server/routes/open-in-editor.js +40 -0
  31. package/dist/preview-server/routes/register-client-render.d.ts +3 -0
  32. package/dist/preview-server/routes/register-client-render.js +11 -0
  33. package/dist/preview-server/routes/save-effect-props.js +1 -0
  34. package/dist/preview-server/routes/save-sequence-props.js +158 -72
  35. package/dist/preview-server/routes/unregister-client-render.d.ts +4 -0
  36. package/dist/preview-server/routes/unregister-client-render.js +11 -0
  37. package/dist/preview-server/routes/update-default-props.js +1 -0
  38. package/dist/preview-server/start-server.d.ts +1 -0
  39. package/dist/preview-server/start-server.js +1 -0
  40. package/dist/preview-server/undo-stack.d.ts +26 -3
  41. package/dist/preview-server/undo-stack.js +130 -42
  42. package/dist/preview-server/validate-same-origin.d.ts +2 -0
  43. package/dist/preview-server/validate-same-origin.js +13 -0
  44. package/dist/routes.d.ts +2 -1
  45. package/dist/routes.js +9 -136
  46. package/dist/start-studio.d.ts +2 -1
  47. package/dist/start-studio.js +2 -1
  48. package/package.json +6 -6
@@ -211,12 +211,9 @@ const getKeyframeEasingArray = ({ easingNode, segments, }) => {
211
211
  }
212
212
  return new Array(segments).fill(easing);
213
213
  };
214
- const getInterpolationMetadata = (callExpression, keyframeCount) => {
214
+ const getInterpolationMetadata = (interpolationFunction, callExpression, keyframeCount) => {
215
215
  const segments = Math.max(0, keyframeCount - 1);
216
- if (callExpression.callee.type !== 'Identifier') {
217
- return null;
218
- }
219
- const defaultClamping = callExpression.callee.name === 'interpolateColors'
216
+ const defaultClamping = interpolationFunction === 'interpolateColors'
220
217
  ? {
221
218
  left: 'clamp',
222
219
  right: 'clamp',
@@ -228,13 +225,8 @@ const getInterpolationMetadata = (callExpression, keyframeCount) => {
228
225
  const defaults = {
229
226
  easing: new Array(segments).fill('linear'),
230
227
  clamping: defaultClamping,
228
+ posterize: undefined,
231
229
  };
232
- if (callExpression.callee.name === 'interpolateColors') {
233
- return defaults;
234
- }
235
- if (callExpression.callee.name !== 'interpolate') {
236
- return null;
237
- }
238
230
  const optionsArg = callExpression.arguments[3];
239
231
  if (!optionsArg) {
240
232
  return defaults;
@@ -244,6 +236,7 @@ const getInterpolationMetadata = (callExpression, keyframeCount) => {
244
236
  }
245
237
  let { easing } = defaults;
246
238
  let { clamping } = defaults;
239
+ let posterize;
247
240
  for (const property of optionsArg.properties) {
248
241
  if (property.type !== 'ObjectProperty' || property.computed) {
249
242
  return null;
@@ -258,6 +251,9 @@ const getInterpolationMetadata = (callExpression, keyframeCount) => {
258
251
  }
259
252
  const value = property.value;
260
253
  if (key === 'easing') {
254
+ if (interpolationFunction === 'interpolateColors') {
255
+ return null;
256
+ }
261
257
  const parsedEasing = getKeyframeEasingArray({
262
258
  easingNode: value,
263
259
  segments,
@@ -269,6 +265,9 @@ const getInterpolationMetadata = (callExpression, keyframeCount) => {
269
265
  continue;
270
266
  }
271
267
  if (key === 'extrapolateLeft' || key === 'extrapolateRight') {
268
+ if (interpolationFunction === 'interpolateColors') {
269
+ return null;
270
+ }
272
271
  const extrapolateType = getExtrapolateType(value);
273
272
  if (!extrapolateType) {
274
273
  return null;
@@ -277,9 +276,25 @@ const getInterpolationMetadata = (callExpression, keyframeCount) => {
277
276
  key === 'extrapolateLeft'
278
277
  ? { ...clamping, left: extrapolateType }
279
278
  : { ...clamping, right: extrapolateType };
279
+ continue;
280
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;
281
292
  }
282
- return { easing, clamping };
293
+ return {
294
+ easing,
295
+ clamping,
296
+ posterize,
297
+ };
283
298
  };
284
299
  const getInterpolationKeyframes = (node) => {
285
300
  if (node.type === 'TSAsExpression') {
@@ -294,6 +309,7 @@ const getInterpolationKeyframes = (node) => {
294
309
  callExpression.callee.name !== 'interpolateColors')) {
295
310
  return undefined;
296
311
  }
312
+ const interpolationFunction = callExpression.callee.name;
297
313
  const inputArg = callExpression.arguments[1];
298
314
  const outputArg = callExpression.arguments[2];
299
315
  if (!inputArg ||
@@ -327,14 +343,16 @@ const getInterpolationKeyframes = (node) => {
327
343
  if (keyframes.length === 0) {
328
344
  return undefined;
329
345
  }
330
- const metadata = getInterpolationMetadata(callExpression, keyframes.length);
346
+ const metadata = getInterpolationMetadata(interpolationFunction, callExpression, keyframes.length);
331
347
  if (!metadata) {
332
348
  return undefined;
333
349
  }
334
350
  return {
351
+ interpolationFunction,
335
352
  keyframes,
336
353
  easing: metadata.easing,
337
354
  clamping: metadata.clamping,
355
+ posterize: metadata.posterize,
338
356
  };
339
357
  };
340
358
  const getComputedStatus = (node) => {
@@ -345,9 +363,11 @@ const getComputedStatus = (node) => {
345
363
  return {
346
364
  canUpdate: false,
347
365
  reason: 'keyframed',
366
+ interpolationFunction: interpolation.interpolationFunction,
348
367
  keyframes: interpolation.keyframes,
349
368
  easing: interpolation.easing,
350
369
  clamping: interpolation.clamping,
370
+ posterize: interpolation.posterize,
351
371
  };
352
372
  };
353
373
  exports.getComputedStatus = getComputedStatus;
@@ -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 deleteEffectHandler = async ({ input: { fileName, sequenceNodePath, effectIndex }, remotionRoot, logLevel, }) => {
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
- renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-effect] Received request for fileName="${fileName}" effectIndex=${effectIndex}`);
16
- const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
17
- remotionRoot,
18
- fileName,
19
- action: 'modify',
20
- });
21
- const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
22
- const { output, formatted, effectLabel, logLine } = await (0, delete_effect_1.deleteEffect)({
23
- input: fileContents,
24
- sequenceNodePath: sequenceNodePath.nodePath,
25
- effectIndex,
26
- });
27
- (0, undo_stack_1.pushToUndoStack)({
28
- filePath: absolutePath,
29
- oldContents: fileContents,
30
- logLevel,
31
- remotionRoot,
32
- logLine,
33
- description: {
34
- undoMessage: `↩️ Deletion of ${effectLabel}`,
35
- redoMessage: `↪️ Deletion of ${effectLabel}`,
36
- },
37
- entryType: 'delete-effect',
38
- suppressHmrOnFileRestore: false,
39
- });
40
- (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
41
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, undefined);
42
- const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
43
- remotionRoot,
44
- absolutePath,
45
- line: logLine,
46
- });
47
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} ${(0, formatting_1.strikeThroughOrRemovedPrefix)(effectLabel)}`);
48
- if (!formatted) {
49
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
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 deleteJsxNodeHandler = async ({ input: { fileName, nodePath }, remotionRoot, logLevel }) => {
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
- renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-jsx-node] Received request for fileName="${fileName}"`);
15
- const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
16
- remotionRoot,
17
- fileName,
18
- action: 'modify',
19
- });
20
- const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
21
- const { output, formatted, nodeLabel, logLine } = await (0, delete_jsx_node_1.deleteJsxNode)({
22
- input: fileContents,
23
- nodePath,
24
- });
25
- (0, undo_stack_1.pushToUndoStack)({
26
- filePath: absolutePath,
27
- oldContents: fileContents,
28
- logLevel,
29
- remotionRoot,
30
- logLine,
31
- description: {
32
- undoMessage: `↩️ Deletion of ${nodeLabel}`,
33
- redoMessage: `↪️ Deletion of ${nodeLabel}`,
34
- },
35
- entryType: 'delete-jsx-node',
36
- suppressHmrOnFileRestore: false,
37
- });
38
- (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
39
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, undefined);
40
- const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
41
- remotionRoot,
42
- absolutePath,
43
- line: logLine,
44
- });
45
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Deleted ${nodeLabel}`);
46
- if (!formatted) {
47
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
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>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteSequenceKeyframeHandler = 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 update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
8
+ const file_watcher_1 = require("../../file-watcher");
9
+ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
10
+ const undo_stack_1 = require("../undo-stack");
11
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
12
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
13
+ const log_update_1 = require("./log-updates/log-update");
14
+ const save_props_mutex_1 = require("./save-props-mutex");
15
+ const deleteSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, schema, clientId }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
16
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-sequence-keyframe] Received request for fileName="${fileName}" key="${key}" frame=${frame}`);
17
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
18
+ remotionRoot,
19
+ fileName,
20
+ action: 'modify',
21
+ });
22
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
23
+ const { output, oldValueStrings, newValueStrings, formatted, logLine } = await (0, update_keyframes_1.updateSequenceKeyframes)({
24
+ input: fileContents,
25
+ nodePath: nodePath.nodePath,
26
+ updates: [
27
+ {
28
+ key,
29
+ operation: {
30
+ type: 'remove',
31
+ frame,
32
+ },
33
+ },
34
+ ],
35
+ });
36
+ const oldValueString = oldValueStrings[0];
37
+ const newValueString = newValueStrings[0];
38
+ const undoPropChange = `${key} keyframe restored at frame ${frame}`;
39
+ const redoPropChange = `${key} keyframe deleted at frame ${frame}`;
40
+ (0, undo_stack_1.pushToUndoStack)({
41
+ filePath: absolutePath,
42
+ oldContents: fileContents,
43
+ newContents: null,
44
+ logLevel,
45
+ remotionRoot,
46
+ logLine,
47
+ description: {
48
+ undoMessage: `↩️ ${undoPropChange}`,
49
+ redoMessage: `↪️ ${redoPropChange}`,
50
+ },
51
+ entryType: 'sequence-props',
52
+ suppressHmrOnFileRestore: true,
53
+ });
54
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
55
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
56
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
57
+ (0, log_update_1.logUpdate)({
58
+ fileRelativeToRoot,
59
+ line: logLine,
60
+ key,
61
+ oldValueString,
62
+ newValueString,
63
+ defaultValueString: null,
64
+ formatted,
65
+ logLevel,
66
+ removedProps: [],
67
+ addedProps: [],
68
+ });
69
+ (0, undo_stack_1.printUndoHint)(logLevel);
70
+ const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
71
+ fileContents: output,
72
+ keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
73
+ nodePath: nodePath.nodePath,
74
+ effects: [],
75
+ });
76
+ return {
77
+ canUpdate: true,
78
+ props: status.props,
79
+ results: [{ fileName, nodePath, props: status.props }],
80
+ };
81
+ });
82
+ exports.deleteSequenceKeyframeHandler = deleteSequenceKeyframeHandler;
@@ -25,6 +25,7 @@ const duplicateJsxNodeHandler = async ({ input: { fileName, nodePath }, remotion
25
25
  (0, undo_stack_1.pushToUndoStack)({
26
26
  filePath: absolutePath,
27
27
  oldContents: fileContents,
28
+ newContents: null,
28
29
  logLevel,
29
30
  remotionRoot,
30
31
  logLine,
@@ -0,0 +1,4 @@
1
+ import type { OpenInEditorRequest, OpenInEditorResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const getEditorName: () => Promise<string | null>;
4
+ export declare const openInEditorHandler: ApiHandler<OpenInEditorRequest, OpenInEditorResponse>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.openInEditorHandler = exports.getEditorName = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const open_in_editor_1 = require("../../helpers/open-in-editor");
9
+ const editorGuess = (0, open_in_editor_1.guessEditor)();
10
+ const getEditorName = async () => {
11
+ const [edit] = await editorGuess;
12
+ return (0, open_in_editor_1.getDisplayNameForEditor)(edit ? edit.command : null);
13
+ };
14
+ exports.getEditorName = getEditorName;
15
+ const openInEditorHandler = async ({ input, remotionRoot, logLevel }) => {
16
+ try {
17
+ if (!('stack' in input)) {
18
+ throw new TypeError('Need to pass stack');
19
+ }
20
+ const { stack } = input;
21
+ const guess = await editorGuess;
22
+ const didOpen = await (0, open_in_editor_1.launchEditor)({
23
+ colNumber: stack.originalColumnNumber,
24
+ editor: guess[0],
25
+ fileName: node_path_1.default.resolve(remotionRoot, stack.originalFileName),
26
+ lineNumber: stack.originalLineNumber,
27
+ vsCodeNewWindow: false,
28
+ logLevel,
29
+ });
30
+ return {
31
+ success: didOpen,
32
+ };
33
+ }
34
+ catch (_a) {
35
+ return {
36
+ success: false,
37
+ };
38
+ }
39
+ };
40
+ exports.openInEditorHandler = openInEditorHandler;
@@ -0,0 +1,3 @@
1
+ import type { CompletedClientRender } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const registerClientRenderHandler: ApiHandler<CompletedClientRender, void>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerClientRenderHandler = void 0;
4
+ const client_render_queue_1 = require("../../client-render-queue");
5
+ const validate_same_origin_1 = require("../validate-same-origin");
6
+ const registerClientRenderHandler = ({ input, remotionRoot, request }) => {
7
+ (0, validate_same_origin_1.validateSameOrigin)(request);
8
+ (0, client_render_queue_1.addCompletedClientRender)({ render: input, remotionRoot });
9
+ return Promise.resolve();
10
+ };
11
+ exports.registerClientRenderHandler = registerClientRenderHandler;
@@ -65,6 +65,7 @@ const saveEffectPropsHandler = ({ input: { fileName, sequenceNodePath, effectInd
65
65
  (0, undo_stack_1.pushToUndoStack)({
66
66
  filePath: absolutePath,
67
67
  oldContents: fileContents,
68
+ newContents: null,
68
69
  logLevel,
69
70
  remotionRoot,
70
71
  logLine,