@remotion/studio-server 4.0.478 → 4.0.481

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.
@@ -38,7 +38,7 @@ const recast = __importStar(require("recast"));
38
38
  const imports_1 = require("../helpers/imports");
39
39
  const update_nested_prop_1 = require("./update-nested-prop");
40
40
  const b = recast.types.builders;
41
- const isNonLinearEasing = (easing) => easing !== 'linear';
41
+ const isNonLinearEasing = (easing) => easing.type !== 'linear';
42
42
  const keyframedParamNeedsEasingImport = (param) => param.easing.some(isNonLinearEasing);
43
43
  const getRequiredRemotionImportsForEffectParams = (params) => {
44
44
  const requiredImports = new Set();
@@ -73,10 +73,23 @@ const ensureRemotionImportLocalNames = ({ ast, requiredImports, }) => {
73
73
  };
74
74
  exports.ensureRemotionImportLocalNames = ensureRemotionImportLocalNames;
75
75
  const makeEasingExpression = ({ easing, easingLocalName, }) => {
76
- if (easing === 'linear') {
77
- return b.memberExpression(b.identifier(easingLocalName), b.identifier('linear'));
76
+ switch (easing.type) {
77
+ case 'linear':
78
+ return b.memberExpression(b.identifier(easingLocalName), b.identifier('linear'));
79
+ case 'spring':
80
+ return b.callExpression(b.memberExpression(b.identifier(easingLocalName), b.identifier('spring')), [
81
+ b.objectExpression([
82
+ b.objectProperty(b.identifier('damping'), (0, update_nested_prop_1.parseValueExpression)(easing.damping)),
83
+ b.objectProperty(b.identifier('mass'), (0, update_nested_prop_1.parseValueExpression)(easing.mass)),
84
+ b.objectProperty(b.identifier('stiffness'), (0, update_nested_prop_1.parseValueExpression)(easing.stiffness)),
85
+ b.objectProperty(b.identifier('overshootClamping'), b.booleanLiteral(easing.overshootClamping)),
86
+ ]),
87
+ ]);
88
+ case 'bezier':
89
+ return b.callExpression(b.memberExpression(b.identifier(easingLocalName), b.identifier('bezier')), [easing.x1, easing.y1, easing.x2, easing.y2].map((value) => (0, update_nested_prop_1.parseValueExpression)(value)));
90
+ default:
91
+ throw new Error(`Unsupported easing: ${JSON.stringify(easing)}`);
78
92
  }
79
- return b.callExpression(b.memberExpression(b.identifier(easingLocalName), b.identifier('bezier')), easing.map((value) => (0, update_nested_prop_1.parseValueExpression)(value)));
80
93
  };
81
94
  const makeKeyframedOptions = ({ param, remotionLocalNames, }) => {
82
95
  var _a;
@@ -1,6 +1,6 @@
1
1
  import type { ArrayExpression, CallExpression, JSXAttribute } from '@babel/types';
2
2
  import type { EffectClipboardParam } from '@remotion/studio-shared';
3
- import type { SequenceNodePath, SequenceSchema } from 'remotion';
3
+ import type { SequenceNodePath, InteractivitySchema } from 'remotion';
4
4
  export type EffectPropUpdate = {
5
5
  key: string;
6
6
  value: unknown;
@@ -49,7 +49,7 @@ export declare const updateEffectPropsAst: ({ input, sequenceNodePath, effectInd
49
49
  sequenceNodePath: SequenceNodePath;
50
50
  effectIndex: number;
51
51
  update: EffectPropUpdate;
52
- schema: SequenceSchema;
52
+ schema: InteractivitySchema;
53
53
  }) => {
54
54
  serialized: string;
55
55
  oldValueString: string;
@@ -63,6 +63,6 @@ export declare const updateEffectProps: ({ input, sequenceNodePath, effectIndex,
63
63
  sequenceNodePath: SequenceNodePath;
64
64
  effectIndex: number;
65
65
  update: EffectPropUpdate;
66
- schema: SequenceSchema;
66
+ schema: InteractivitySchema;
67
67
  prettierConfigOverride?: Record<string, unknown> | null | undefined;
68
68
  }) => Promise<UpdateEffectPropsResult>;
@@ -1,5 +1,5 @@
1
1
  import { type KeyframeInterpolationFunction } from '@remotion/studio-shared';
2
- import type { CanUpdateSequencePropStatus, ExtrapolateType, SequenceNodePath, SequenceSchema } from 'remotion';
2
+ import type { CanUpdateSequencePropStatus, ExtrapolateType, SequenceNodePath, InteractivitySchema } from 'remotion';
3
3
  type KeyframeEasing = Extract<CanUpdateSequencePropStatus, {
4
4
  status: 'keyframed';
5
5
  }>['easing'][number];
@@ -45,7 +45,7 @@ export declare const updateSequenceKeyframesAst: ({ input, nodePath, updates, sc
45
45
  input: string;
46
46
  nodePath: SequenceNodePath;
47
47
  updates: SequenceKeyframeUpdate[];
48
- schema?: SequenceSchema | undefined;
48
+ schema?: InteractivitySchema | undefined;
49
49
  }) => {
50
50
  serialized: string;
51
51
  oldValueStrings: string[];
@@ -57,7 +57,7 @@ export declare const updateSequenceKeyframes: ({ input, nodePath, updates, schem
57
57
  input: string;
58
58
  nodePath: SequenceNodePath;
59
59
  updates: SequenceKeyframeUpdate[];
60
- schema?: SequenceSchema | undefined;
60
+ schema?: InteractivitySchema | undefined;
61
61
  prettierConfigOverride?: Record<string, unknown> | null | undefined;
62
62
  }) => Promise<{
63
63
  output: string;
@@ -72,7 +72,7 @@ export declare const updateEffectKeyframesAst: ({ input, sequenceNodePath, effec
72
72
  sequenceNodePath: SequenceNodePath;
73
73
  effectIndex: number;
74
74
  updates: EffectKeyframeUpdate[];
75
- schema?: SequenceSchema | undefined;
75
+ schema?: InteractivitySchema | undefined;
76
76
  }) => {
77
77
  serialized: string;
78
78
  oldValueStrings: string[];
@@ -86,7 +86,7 @@ export declare const updateEffectKeyframes: ({ input, sequenceNodePath, effectIn
86
86
  sequenceNodePath: SequenceNodePath;
87
87
  effectIndex: number;
88
88
  updates: EffectKeyframeUpdate[];
89
- schema?: SequenceSchema | undefined;
89
+ schema?: InteractivitySchema | undefined;
90
90
  prettierConfigOverride?: Record<string, unknown> | null | undefined;
91
91
  }) => Promise<{
92
92
  output: string;
@@ -224,7 +224,7 @@ const setOptionsProperty = ({ options, propertyName, value, }) => {
224
224
  }
225
225
  options.properties.push(b.objectProperty(b.identifier(propertyName), value));
226
226
  };
227
- const isLinearEasing = (easing) => easing === 'linear';
227
+ const isLinearEasing = (easing) => easing.type === 'linear';
228
228
  const getKeyframeEasing = (node) => {
229
229
  if (node.type === 'TSAsExpression') {
230
230
  return getKeyframeEasing(node.expression);
@@ -235,16 +235,29 @@ const getKeyframeEasing = (node) => {
235
235
  node.property.type === 'Identifier' &&
236
236
  node.property.name === 'linear' &&
237
237
  node.computed === false) {
238
- return 'linear';
238
+ return { type: 'linear' };
239
239
  }
240
240
  if (node.type !== 'CallExpression' ||
241
241
  node.callee.type !== 'MemberExpression' ||
242
242
  node.callee.object.type !== 'Identifier' ||
243
243
  node.callee.object.name !== 'Easing' ||
244
244
  node.callee.property.type !== 'Identifier' ||
245
- node.callee.property.name !== 'bezier' ||
246
- node.callee.computed ||
247
- node.arguments.length !== 4) {
245
+ node.callee.computed) {
246
+ return null;
247
+ }
248
+ if (node.callee.property.name === 'spring') {
249
+ if (node.arguments.length > 1) {
250
+ return null;
251
+ }
252
+ const springConfig = node.arguments[0];
253
+ if ((springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'ArgumentPlaceholder' ||
254
+ (springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'JSXNamespacedName' ||
255
+ (springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'SpreadElement') {
256
+ return null;
257
+ }
258
+ return (0, studio_shared_1.parseSpringEasingConfig)(springConfig);
259
+ }
260
+ if (node.callee.property.name !== 'bezier' || node.arguments.length !== 4) {
248
261
  return null;
249
262
  }
250
263
  const values = node.arguments.map((arg) => {
@@ -258,7 +271,8 @@ const getKeyframeEasing = (node) => {
258
271
  if (values.some((value) => value === null)) {
259
272
  return null;
260
273
  }
261
- return values;
274
+ const [x1, y1, x2, y2] = values;
275
+ return { type: 'bezier', x1, y1, x2, y2 };
262
276
  };
263
277
  const getKeyframeEasingArray = ({ easingNode, segmentCount, }) => {
264
278
  if (segmentCount === 0) {
@@ -285,7 +299,7 @@ const getKeyframeEasingArray = ({ easingNode, segmentCount, }) => {
285
299
  }
286
300
  const easingArray = parsed;
287
301
  while (easingArray.length < segmentCount) {
288
- easingArray.push('linear');
302
+ easingArray.push(studio_shared_1.LINEAR_KEYFRAME_EASING);
289
303
  }
290
304
  return easingArray;
291
305
  }
@@ -298,7 +312,7 @@ const getKeyframeEasingArray = ({ easingNode, segmentCount, }) => {
298
312
  const getExistingEasingArray = ({ options, segmentCount, }) => {
299
313
  const { prop } = findObjectOptionProperty(options, 'easing');
300
314
  if (!prop) {
301
- return new Array(segmentCount).fill('linear');
315
+ return Array.from({ length: segmentCount }, () => ({ type: 'linear' }));
302
316
  }
303
317
  const easing = getKeyframeEasingArray({
304
318
  easingNode: prop.value,
@@ -317,10 +331,23 @@ const getExistingEasingArrayOrNull = ({ options, segmentCount, }) => {
317
331
  return getExistingEasingArray({ options, segmentCount });
318
332
  };
319
333
  const createEasingExpression = (easing) => {
320
- if (easing === 'linear') {
321
- return b.memberExpression(b.identifier('Easing'), b.identifier('linear'));
334
+ switch (easing.type) {
335
+ case 'linear':
336
+ return b.memberExpression(b.identifier('Easing'), b.identifier('linear'));
337
+ case 'spring':
338
+ return b.callExpression(b.memberExpression(b.identifier('Easing'), b.identifier('spring')), [
339
+ b.objectExpression([
340
+ b.objectProperty(b.identifier('damping'), (0, update_nested_prop_1.parseValueExpression)(easing.damping)),
341
+ b.objectProperty(b.identifier('mass'), (0, update_nested_prop_1.parseValueExpression)(easing.mass)),
342
+ b.objectProperty(b.identifier('stiffness'), (0, update_nested_prop_1.parseValueExpression)(easing.stiffness)),
343
+ b.objectProperty(b.identifier('overshootClamping'), b.booleanLiteral(easing.overshootClamping)),
344
+ ]),
345
+ ]);
346
+ case 'bezier':
347
+ return b.callExpression(b.memberExpression(b.identifier('Easing'), b.identifier('bezier')), [easing.x1, easing.y1, easing.x2, easing.y2].map((value) => (0, update_nested_prop_1.parseValueExpression)(value)));
348
+ default:
349
+ throw new Error(`Unsupported easing: ${JSON.stringify(easing)}`);
322
350
  }
323
- return b.callExpression(b.memberExpression(b.identifier('Easing'), b.identifier('bezier')), easing.map((value) => (0, update_nested_prop_1.parseValueExpression)(value)));
324
351
  };
325
352
  const createEasingArrayExpression = (easing) => b.arrayExpression(easing.map((easingValue) => createEasingExpression(easingValue)));
326
353
  const setEasingOption = ({ options, easing, }) => {
@@ -357,7 +384,7 @@ const normalizeEasingAfterAddingKeyframe = ({ extraArgs, previousSegmentCount, n
357
384
  return { extraArgs, needsEasingImport: false };
358
385
  }
359
386
  while (easing.length < nextSegmentCount) {
360
- easing.push('linear');
387
+ easing.push(studio_shared_1.LINEAR_KEYFRAME_EASING);
361
388
  }
362
389
  return {
363
390
  extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
@@ -384,7 +411,7 @@ const normalizeEasingAfterRemovingKeyframe = ({ extraArgs, previousSegmentCount,
384
411
  easing.pop();
385
412
  }
386
413
  while (easing.length < nextSegmentCount) {
387
- easing.push('linear');
414
+ easing.push(studio_shared_1.LINEAR_KEYFRAME_EASING);
388
415
  }
389
416
  return {
390
417
  extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
@@ -414,7 +441,7 @@ const normalizeEasingAfterRemovingKeyframes = ({ extraArgs, previousSegmentCount
414
441
  easing.pop();
415
442
  }
416
443
  while (easing.length < nextSegmentCount) {
417
- easing.push('linear');
444
+ easing.push(studio_shared_1.LINEAR_KEYFRAME_EASING);
418
445
  }
419
446
  return {
420
447
  extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
@@ -901,6 +928,37 @@ const getSequenceWritableProp = ({ attributes, key, missingPropInitialValue, })
901
928
  },
902
929
  };
903
930
  };
931
+ const getEffectWritableProp = ({ objExpr, key, missingPropInitialValue, }) => {
932
+ const { prop } = findObjectProperty(objExpr, key);
933
+ if (!prop) {
934
+ if (missingPropInitialValue) {
935
+ return {
936
+ expression: createMissingPropExpression(missingPropInitialValue),
937
+ setExpression: (nextExpression) => {
938
+ objExpr.properties.push(createObjectProperty(key, nextExpression));
939
+ },
940
+ };
941
+ }
942
+ throw new Error(`Cannot update keyframes: "${key}" is not set`);
943
+ }
944
+ return {
945
+ expression: prop.value,
946
+ setExpression: (nextExpression) => {
947
+ prop.value = nextExpression;
948
+ },
949
+ };
950
+ };
951
+ const getEffectPropsObjectExpression = (call) => {
952
+ if (call.arguments.length === 0) {
953
+ const objExpr = b.objectExpression([]);
954
+ call.arguments.push(objExpr);
955
+ return objExpr;
956
+ }
957
+ if (call.arguments[0].type !== 'ObjectExpression') {
958
+ throw new Error('Cannot update effect keyframe: computed');
959
+ }
960
+ return call.arguments[0];
961
+ };
904
962
  const updateSequenceKeyframesAst = ({ input, nodePath, updates, schema, }) => {
905
963
  var _a;
906
964
  var _b;
@@ -1014,29 +1072,34 @@ const updateEffectKeyframesAst = ({ input, sequenceNodePath, effectIndex, update
1014
1072
  throw new Error(`Cannot update effect keyframe: ${found.reason}`);
1015
1073
  }
1016
1074
  const { call, callee: effectCallee } = found;
1017
- if (call.arguments.length === 0 ||
1018
- call.arguments[0].type !== 'ObjectExpression') {
1019
- throw new Error('Cannot update effect keyframe: computed');
1020
- }
1021
- const objExpr = call.arguments[0];
1075
+ const objExpr = getEffectPropsObjectExpression(call);
1022
1076
  const oldValueStrings = [];
1023
1077
  const newValueStrings = [];
1024
1078
  const requiredImports = new Set();
1025
1079
  let needsFrameHook = false;
1026
1080
  for (const update of updates) {
1027
- const { prop } = findObjectProperty(objExpr, update.key);
1028
- if (!prop) {
1029
- throw new Error(`Cannot update keyframes: "${update.key}" is not set`);
1030
- }
1031
- oldValueStrings.push(recast.print(prop.value).code);
1081
+ const prop = getEffectWritableProp({
1082
+ objExpr,
1083
+ key: update.key,
1084
+ missingPropInitialValue: update.operation.type === 'add'
1085
+ ? {
1086
+ value: getInitialValueForMissingProp({
1087
+ schema: schema !== null && schema !== void 0 ? schema : null,
1088
+ key: update.key,
1089
+ newValue: update.operation.value,
1090
+ }),
1091
+ }
1092
+ : null,
1093
+ });
1094
+ oldValueStrings.push(recast.print(prop.expression).code);
1032
1095
  const { expression: nextExpression, introduced } = applyKeyframeOperation({
1033
- expression: prop.value,
1096
+ expression: prop.expression,
1034
1097
  key: update.key,
1035
1098
  operation: update.operation,
1036
1099
  schema: schema !== null && schema !== void 0 ? schema : null,
1037
1100
  });
1038
1101
  newValueStrings.push(recast.print(nextExpression).code);
1039
- prop.value = nextExpression;
1102
+ prop.setExpression(nextExpression);
1040
1103
  if (introduced.calleeName) {
1041
1104
  requiredImports.add(introduced.calleeName);
1042
1105
  }
@@ -1,4 +1,4 @@
1
- import type { SequenceNodePath, SequenceSchema } from 'remotion';
1
+ import type { SequenceNodePath, InteractivitySchema } from 'remotion';
2
2
  export type SequencePropUpdate = {
3
3
  key: string;
4
4
  value: unknown;
@@ -11,7 +11,7 @@ export type RemovedProp = {
11
11
  export type SequencePropsNodeUpdate = {
12
12
  nodePath: SequenceNodePath;
13
13
  updates: SequencePropUpdate[];
14
- schema: SequenceSchema;
14
+ schema: InteractivitySchema;
15
15
  };
16
16
  export type SequencePropsNodeUpdateResult = {
17
17
  oldValueStrings: string[];
@@ -35,7 +35,7 @@ export declare const updateSequencePropsAst: ({ input, nodePath, updates, schema
35
35
  input: string;
36
36
  nodePath: SequenceNodePath;
37
37
  updates: SequencePropUpdate[];
38
- schema: SequenceSchema;
38
+ schema: InteractivitySchema;
39
39
  }) => {
40
40
  serialized: string;
41
41
  oldValueStrings: string[];
@@ -51,7 +51,7 @@ export declare const updateSequenceProps: ({ input, nodePath, updates, schema, p
51
51
  input: string;
52
52
  nodePath: SequenceNodePath;
53
53
  updates: SequencePropUpdate[];
54
- schema: SequenceSchema;
54
+ schema: InteractivitySchema;
55
55
  prettierConfigOverride: PrettierConfigOverride;
56
56
  }) => Promise<UpdateSequencePropsResult>;
57
57
  export {};
@@ -515,7 +515,13 @@ const createStringAttribute = (name, value) => {
515
515
  const createBooleanAttribute = (name, value) => {
516
516
  return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.booleanLiteral(value)));
517
517
  };
518
- const formatTranslateValue = ({ x, y }) => `${x}px ${y}px`;
518
+ const translateDecimalPlaces = 1;
519
+ const roundTranslateCoordinate = (value) => {
520
+ const factor = 10 ** translateDecimalPlaces;
521
+ const rounded = Math.round(value * factor) / factor;
522
+ return Object.is(rounded, -0) ? 0 : rounded;
523
+ };
524
+ const formatTranslateValue = ({ x, y }) => `${roundTranslateCoordinate(x)}px ${roundTranslateCoordinate(y)}px`;
519
525
  const createPositionAbsoluteStyleAttribute = (position) => {
520
526
  const properties = [
521
527
  recast.types.builders.objectProperty(recast.types.builders.identifier('position'), recast.types.builders.stringLiteral('absolute')),
@@ -1,5 +1,5 @@
1
1
  import type { File, JSXOpeningElement } from '@babel/types';
2
- import type { CanUpdateEffectPropsResponse, SequenceNodePath, SequenceSchema } from 'remotion';
2
+ import type { CanUpdateEffectPropsResponse, SequenceNodePath, InteractivitySchema } from 'remotion';
3
3
  export declare const computeEffectPropStatus: ({ ast, jsx, effectIndex, keys, }: {
4
4
  ast: File;
5
5
  jsx: JSXOpeningElement;
@@ -9,13 +9,13 @@ export declare const computeEffectPropStatus: ({ ast, jsx, effectIndex, keys, }:
9
9
  export declare const computeEffectPropsStatusesFromContent: ({ fileContents, sequenceNodePath, effects, keysFor, }: {
10
10
  fileContents: string;
11
11
  sequenceNodePath: SequenceNodePath;
12
- effects: SequenceSchema[];
13
- keysFor: (effect: SequenceSchema) => string[];
12
+ effects: InteractivitySchema[];
13
+ keysFor: (effect: InteractivitySchema) => string[];
14
14
  }) => CanUpdateEffectPropsResponse[];
15
15
  export declare const computeEffectPropsStatusesFromFile: ({ fileName, sequenceNodePath, effects, keysFor, remotionRoot, }: {
16
16
  fileName: string;
17
17
  sequenceNodePath: SequenceNodePath;
18
- effects: SequenceSchema[];
19
- keysFor: (effect: SequenceSchema) => string[];
18
+ effects: InteractivitySchema[];
19
+ keysFor: (effect: InteractivitySchema) => string[];
20
20
  remotionRoot: string;
21
21
  }) => CanUpdateEffectPropsResponse[];
@@ -210,18 +210,29 @@ const getKeyframeEasing = (node) => {
210
210
  node.property.type === 'Identifier' &&
211
211
  node.property.name === 'linear' &&
212
212
  node.computed === false) {
213
- return 'linear';
213
+ return { type: 'linear' };
214
214
  }
215
215
  if (node.type !== 'CallExpression' ||
216
216
  node.callee.type !== 'MemberExpression' ||
217
217
  node.callee.object.type !== 'Identifier' ||
218
218
  node.callee.object.name !== 'Easing' ||
219
219
  node.callee.property.type !== 'Identifier' ||
220
- node.callee.property.name !== 'bezier' ||
221
220
  node.callee.computed) {
222
221
  return null;
223
222
  }
224
- if (node.arguments.length !== 4) {
223
+ if (node.callee.property.name === 'spring') {
224
+ if (node.arguments.length > 1) {
225
+ return null;
226
+ }
227
+ const springConfig = node.arguments[0];
228
+ if ((springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'ArgumentPlaceholder' ||
229
+ (springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'JSXNamespacedName' ||
230
+ (springConfig === null || springConfig === void 0 ? void 0 : springConfig.type) === 'SpreadElement') {
231
+ return null;
232
+ }
233
+ return (0, studio_shared_1.parseSpringEasingConfig)(springConfig);
234
+ }
235
+ if (node.callee.property.name !== 'bezier' || node.arguments.length !== 4) {
225
236
  return null;
226
237
  }
227
238
  const values = node.arguments.map((arg) => {
@@ -235,7 +246,8 @@ const getKeyframeEasing = (node) => {
235
246
  if (values.some((v) => v === null)) {
236
247
  return null;
237
248
  }
238
- return values;
249
+ const [x1, y1, x2, y2] = values;
250
+ return { type: 'bezier', x1, y1, x2, y2 };
239
251
  };
240
252
  const getKeyframeEasingArray = ({ easingNode, segments, }) => {
241
253
  if (segments === 0) {
@@ -280,7 +292,7 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
280
292
  right: 'extend',
281
293
  };
282
294
  const defaults = {
283
- easing: new Array(segments).fill('linear'),
295
+ easing: Array.from({ length: segments }, () => studio_shared_1.LINEAR_KEYFRAME_EASING),
284
296
  clamping: defaultClamping,
285
297
  posterize: undefined,
286
298
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
4
4
  },
5
5
  "name": "@remotion/studio-server",
6
- "version": "4.0.478",
6
+ "version": "4.0.481",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -27,11 +27,11 @@
27
27
  "@babel/parser": "7.24.1",
28
28
  "semver": "7.5.3",
29
29
  "prettier": "3.8.1",
30
- "remotion": "4.0.478",
30
+ "remotion": "4.0.481",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.478",
33
- "@remotion/renderer": "4.0.478",
34
- "@remotion/studio-shared": "4.0.478",
32
+ "@remotion/bundler": "4.0.481",
33
+ "@remotion/renderer": "4.0.481",
34
+ "@remotion/studio-shared": "4.0.481",
35
35
  "memfs": "3.4.3",
36
36
  "open": "8.4.2"
37
37
  },
@@ -39,7 +39,7 @@
39
39
  "ast-types": "0.16.1",
40
40
  "react": "19.2.3",
41
41
  "@types/semver": "7.5.3",
42
- "@remotion/eslint-config-internal": "4.0.478",
42
+ "@remotion/eslint-config-internal": "4.0.481",
43
43
  "eslint": "9.19.0",
44
44
  "@types/node": "20.12.14",
45
45
  "@typescript/native-preview": "7.0.0-dev.20260217.1"