@remotion/studio-server 4.0.472 → 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.
Files changed (33) hide show
  1. package/dist/codemods/effect-param-expression.d.ts +15 -0
  2. package/dist/codemods/effect-param-expression.js +131 -0
  3. package/dist/codemods/paste-effects.js +4 -91
  4. package/dist/codemods/reorder-sequence.d.ts +14 -0
  5. package/dist/codemods/reorder-sequence.js +109 -0
  6. package/dist/codemods/update-effect-props/update-effect-props.d.ts +7 -0
  7. package/dist/codemods/update-effect-props/update-effect-props.js +64 -16
  8. package/dist/codemods/update-keyframes/update-keyframes.d.ts +14 -1
  9. package/dist/codemods/update-keyframes/update-keyframes.js +152 -0
  10. package/dist/helpers/resolve-composition-component.js +24 -5
  11. package/dist/preview-server/api-routes.js +14 -0
  12. package/dist/preview-server/routes/can-update-effect-props.js +3 -2
  13. package/dist/preview-server/routes/can-update-sequence-props.d.ts +1 -1
  14. package/dist/preview-server/routes/can-update-sequence-props.js +49 -13
  15. package/dist/preview-server/routes/download-remote-asset.d.ts +7 -0
  16. package/dist/preview-server/routes/download-remote-asset.js +267 -0
  17. package/dist/preview-server/routes/insert-jsx-element.js +3 -0
  18. package/dist/preview-server/routes/log-studio-error.d.ts +3 -0
  19. package/dist/preview-server/routes/log-studio-error.js +58 -0
  20. package/dist/preview-server/routes/move-keyframes.d.ts +7 -0
  21. package/dist/preview-server/routes/move-keyframes.js +242 -0
  22. package/dist/preview-server/routes/rename-static-file.d.ts +3 -0
  23. package/dist/preview-server/routes/rename-static-file.js +53 -0
  24. package/dist/preview-server/routes/reorder-sequence.d.ts +3 -0
  25. package/dist/preview-server/routes/reorder-sequence.js +67 -0
  26. package/dist/preview-server/routes/save-effect-props.js +24 -9
  27. package/dist/preview-server/routes/save-sequence-props.js +2 -34
  28. package/dist/preview-server/routes/update-effect-keyframe-settings.d.ts +3 -0
  29. package/dist/preview-server/routes/update-effect-keyframe-settings.js +90 -0
  30. package/dist/preview-server/routes/update-sequence-keyframe-settings.d.ts +3 -0
  31. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +85 -0
  32. package/dist/preview-server/undo-stack.d.ts +3 -1
  33. package/package.json +6 -6
@@ -141,6 +141,92 @@ const createClampOptionsExpression = () => {
141
141
  b.objectProperty(b.identifier('extrapolateRight'), b.stringLiteral('clamp')),
142
142
  ]);
143
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
+ };
144
230
  const createInterpolateExpression = ({ callee, input, extraArgs, keyframes, }) => {
145
231
  const sortedKeyframes = [...keyframes].sort((first, second) => first.frame - second.frame);
146
232
  return b.callExpression(callee, [
@@ -239,6 +325,56 @@ const removeKeyframe = ({ expression, frame, }) => {
239
325
  keyframes: nextKeyframes,
240
326
  });
241
327
  };
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
+ };
242
378
  const applyKeyframeOperation = ({ expression, key, operation, schema, }) => {
243
379
  if (operation.type === 'add') {
244
380
  return addKeyframe({
@@ -249,6 +385,22 @@ const applyKeyframeOperation = ({ expression, key, operation, schema, }) => {
249
385
  schema,
250
386
  });
251
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
+ }
252
404
  return {
253
405
  expression: removeKeyframe({ expression, frame: operation.frame }),
254
406
  introduced: noIntroducedIdentifiers,
@@ -709,6 +709,14 @@ const ensureVideoImport = (ast) => {
709
709
  label: '<Video>',
710
710
  });
711
711
  };
712
+ const ensureAudioImport = (ast) => {
713
+ return ensureOfficialNamedImport({
714
+ ast,
715
+ importedName: 'Audio',
716
+ sourcePath: '@remotion/media',
717
+ label: '<Audio>',
718
+ });
719
+ };
712
720
  const ensureGifImport = (ast) => {
713
721
  return ensureOfficialNamedImport({
714
722
  ast,
@@ -941,11 +949,22 @@ const createInsertableJsxElement = ({ ast, element, }) => {
941
949
  }
942
950
  if (element.type === 'asset') {
943
951
  const staticFileLocalName = ensureStaticFileImport(ast);
944
- const localName = element.assetType === 'image'
945
- ? ensureImgImport(ast)
946
- : element.assetType === 'video'
947
- ? ensureVideoImport(ast)
948
- : ensureGifImport(ast);
952
+ let localName;
953
+ if (element.assetType === 'image') {
954
+ localName = ensureImgImport(ast);
955
+ }
956
+ else if (element.assetType === 'video') {
957
+ localName = ensureVideoImport(ast);
958
+ }
959
+ else if (element.assetType === 'gif') {
960
+ localName = ensureGifImport(ast);
961
+ }
962
+ else if (element.assetType === 'audio') {
963
+ localName = ensureAudioImport(ast);
964
+ }
965
+ else {
966
+ throw new Error('Unsupported asset type');
967
+ }
949
968
  return createAssetElement({
950
969
  localName,
951
970
  staticFileLocalName,
@@ -13,9 +13,12 @@ const delete_effect_1 = require("./routes/delete-effect");
13
13
  const delete_jsx_node_1 = require("./routes/delete-jsx-node");
14
14
  const delete_keyframes_1 = require("./routes/delete-keyframes");
15
15
  const delete_static_file_1 = require("./routes/delete-static-file");
16
+ const download_remote_asset_1 = require("./routes/download-remote-asset");
16
17
  const duplicate_jsx_node_1 = require("./routes/duplicate-jsx-node");
17
18
  const insert_jsx_element_1 = require("./routes/insert-jsx-element");
18
19
  const install_dependency_1 = require("./routes/install-dependency");
20
+ const log_studio_error_1 = require("./routes/log-studio-error");
21
+ const move_keyframes_1 = require("./routes/move-keyframes");
19
22
  const open_in_editor_1 = require("./routes/open-in-editor");
20
23
  const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
21
24
  const paste_effects_1 = require("./routes/paste-effects");
@@ -23,7 +26,9 @@ const project_info_1 = require("./routes/project-info");
23
26
  const redo_1 = require("./routes/redo");
24
27
  const register_client_render_1 = require("./routes/register-client-render");
25
28
  const remove_render_1 = require("./routes/remove-render");
29
+ const rename_static_file_1 = require("./routes/rename-static-file");
26
30
  const reorder_effect_1 = require("./routes/reorder-effect");
31
+ const reorder_sequence_1 = require("./routes/reorder-sequence");
27
32
  const restart_studio_1 = require("./routes/restart-studio");
28
33
  const save_effect_props_1 = require("./routes/save-effect-props");
29
34
  const save_sequence_props_1 = require("./routes/save-sequence-props");
@@ -37,6 +42,8 @@ const unsubscribe_from_file_existence_1 = require("./routes/unsubscribe-from-fil
37
42
  const unsubscribe_from_sequence_props_1 = require("./routes/unsubscribe-from-sequence-props");
38
43
  const update_available_1 = require("./routes/update-available");
39
44
  const update_default_props_1 = require("./routes/update-default-props");
45
+ const update_effect_keyframe_settings_1 = require("./routes/update-effect-keyframe-settings");
46
+ const update_sequence_keyframe_settings_1 = require("./routes/update-sequence-keyframe-settings");
40
47
  exports.allApiRoutes = {
41
48
  '/api/composition-component-info': composition_component_info_1.compositionComponentInfoHandler,
42
49
  '/api/cancel': cancel_render_1.handleCancelRender,
@@ -59,9 +66,13 @@ exports.allApiRoutes = {
59
66
  '/api/save-effect-props': save_effect_props_1.saveEffectPropsHandler,
60
67
  '/api/add-effect': add_effect_1.addEffectHandler,
61
68
  '/api/reorder-effect': reorder_effect_1.reorderEffectHandler,
69
+ '/api/reorder-sequence': reorder_sequence_1.reorderSequenceHandler,
62
70
  '/api/delete-keyframes': delete_keyframes_1.deleteKeyframesHandler,
71
+ '/api/move-keyframes': move_keyframes_1.moveKeyframesHandler,
63
72
  '/api/add-sequence-keyframe': add_sequence_keyframe_1.addSequenceKeyframeHandler,
64
73
  '/api/add-effect-keyframe': add_effect_keyframe_1.addEffectKeyframeHandler,
74
+ '/api/update-sequence-keyframe-settings': update_sequence_keyframe_settings_1.updateSequenceKeyframeSettingsHandler,
75
+ '/api/update-effect-keyframe-settings': update_effect_keyframe_settings_1.updateEffectKeyframeSettingsHandler,
65
76
  '/api/delete-effect': delete_effect_1.deleteEffectHandler,
66
77
  '/api/paste-effects': paste_effects_1.pasteEffectsHandler,
67
78
  '/api/delete-jsx-node': delete_jsx_node_1.deleteJsxNodeHandler,
@@ -69,9 +80,12 @@ exports.allApiRoutes = {
69
80
  '/api/update-available': update_available_1.handleUpdate,
70
81
  '/api/project-info': project_info_1.projectInfoHandler,
71
82
  '/api/delete-static-file': delete_static_file_1.deleteStaticFileHandler,
83
+ '/api/rename-static-file': rename_static_file_1.renameStaticFileHandler,
72
84
  '/api/restart-studio': restart_studio_1.handleRestartStudio,
73
85
  '/api/install-package': install_dependency_1.handleInstallPackage,
74
86
  '/api/insert-jsx-element': insert_jsx_element_1.insertJsxElementHandler,
87
+ '/api/download-remote-asset': download_remote_asset_1.downloadRemoteAssetHandler,
75
88
  '/api/undo': undo_1.undoHandler,
76
89
  '/api/redo': redo_1.redoHandler,
90
+ '/api/log-studio-error': log_studio_error_1.logStudioErrorHandler,
77
91
  };
@@ -88,7 +88,7 @@ const resolveEffectImport = ({ ast, call, fallbackCallee, }) => {
88
88
  }
89
89
  return { callee: fallbackCallee, importPath: null };
90
90
  };
91
- const getPropsFromObjectExpression = ({ objExpr, keys, }) => {
91
+ const getPropsFromObjectExpression = ({ ast, objExpr, keys, }) => {
92
92
  const out = {};
93
93
  for (const key of keys) {
94
94
  const prop = objExpr.properties.find((p) => p.type === 'ObjectProperty' &&
@@ -101,7 +101,7 @@ const getPropsFromObjectExpression = ({ objExpr, keys, }) => {
101
101
  }
102
102
  const valueExpr = prop.value;
103
103
  if (!(0, can_update_sequence_props_1.isStaticValue)(valueExpr)) {
104
- out[key] = (0, can_update_sequence_props_1.getComputedStatus)(valueExpr);
104
+ out[key] = (0, can_update_sequence_props_1.getComputedStatus)(valueExpr, ast);
105
105
  continue;
106
106
  }
107
107
  out[key] = {
@@ -164,6 +164,7 @@ const computeEffectPropStatus = ({ ast, jsx, effectIndex, keys, }) => {
164
164
  };
165
165
  }
166
166
  const resolvedProps = getPropsFromObjectExpression({
167
+ ast,
167
168
  objExpr: firstArg,
168
169
  keys,
169
170
  });
@@ -3,7 +3,7 @@ import type { SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
3
3
  import type { CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, SequenceNodePath } from 'remotion';
4
4
  export declare const isStaticValue: (node: Expression) => boolean;
5
5
  export declare const extractStaticValue: (node: Expression) => unknown;
6
- export declare const getComputedStatus: (node: Expression) => CanUpdateSequencePropStatus;
6
+ export declare const getComputedStatus: (node: Expression, ast: File) => CanUpdateSequencePropStatus;
7
7
  export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
8
8
  export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
9
9
  export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
@@ -305,9 +305,9 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
305
305
  posterize,
306
306
  };
307
307
  };
308
- const getInterpolationKeyframes = (node) => {
308
+ const getInterpolationKeyframes = (node, ast) => {
309
309
  if (node.type === 'TSAsExpression') {
310
- return getInterpolationKeyframes(node.expression);
310
+ return getInterpolationKeyframes(node.expression, ast);
311
311
  }
312
312
  if (node.type !== 'CallExpression') {
313
313
  return undefined;
@@ -318,9 +318,13 @@ const getInterpolationKeyframes = (node) => {
318
318
  return undefined;
319
319
  }
320
320
  const interpolationFunction = callExpression.callee.name;
321
+ const frameArg = callExpression.arguments[0];
321
322
  const inputArg = callExpression.arguments[1];
322
323
  const outputArg = callExpression.arguments[2];
323
- if (!inputArg ||
324
+ if (!frameArg ||
325
+ frameArg.type === 'SpreadElement' ||
326
+ !isCurrentFrameIdentifier(frameArg, ast) ||
327
+ !inputArg ||
324
328
  !outputArg ||
325
329
  inputArg.type !== 'ArrayExpression' ||
326
330
  outputArg.type !== 'ArrayExpression') {
@@ -363,8 +367,40 @@ const getInterpolationKeyframes = (node) => {
363
367
  posterize: metadata.posterize,
364
368
  };
365
369
  };
366
- const getComputedStatus = (node) => {
367
- const interpolation = getInterpolationKeyframes(node);
370
+ const isUseCurrentFrameCall = (node) => {
371
+ return (node.type === 'CallExpression' &&
372
+ node.callee.type === 'Identifier' &&
373
+ node.callee.name === 'useCurrentFrame' &&
374
+ node.arguments.length === 0);
375
+ };
376
+ const isCurrentFrameIdentifier = (node, ast) => {
377
+ if (node.type === 'TSAsExpression') {
378
+ return isCurrentFrameIdentifier(node.expression, ast);
379
+ }
380
+ if (node.type !== 'Identifier') {
381
+ return false;
382
+ }
383
+ let hasUseCurrentFrameDeclaration = false;
384
+ let hasOtherDeclaration = false;
385
+ recast.types.visit(ast, {
386
+ visitVariableDeclarator(p) {
387
+ const { id, init } = p.node;
388
+ if (id.type !== 'Identifier' || id.name !== node.name) {
389
+ return this.traverse(p);
390
+ }
391
+ if (init && isUseCurrentFrameCall(init)) {
392
+ hasUseCurrentFrameDeclaration = true;
393
+ }
394
+ else {
395
+ hasOtherDeclaration = true;
396
+ }
397
+ return false;
398
+ },
399
+ });
400
+ return hasUseCurrentFrameDeclaration && !hasOtherDeclaration;
401
+ };
402
+ const getComputedStatus = (node, ast) => {
403
+ const interpolation = getInterpolationKeyframes(node, ast);
368
404
  if (!interpolation) {
369
405
  return computedStatus();
370
406
  }
@@ -379,7 +415,7 @@ const getComputedStatus = (node) => {
379
415
  };
380
416
  };
381
417
  exports.getComputedStatus = getComputedStatus;
382
- const getPropsStatus = (jsxElement) => {
418
+ const getPropsStatus = (jsxElement, ast) => {
383
419
  const props = {};
384
420
  for (const attr of jsxElement.attributes) {
385
421
  if (attr.type === 'JSXSpreadAttribute') {
@@ -408,7 +444,7 @@ const getPropsStatus = (jsxElement) => {
408
444
  continue;
409
445
  }
410
446
  if (!(0, exports.isStaticValue)(expression)) {
411
- props[name] = (0, exports.getComputedStatus)(expression);
447
+ props[name] = (0, exports.getComputedStatus)(expression, ast);
412
448
  continue;
413
449
  }
414
450
  props[name] = staticStatus((0, exports.extractStaticValue)(expression));
@@ -488,7 +524,7 @@ const validateStyleValue = (childKey, value) => {
488
524
  }
489
525
  return true;
490
526
  };
491
- const getNestedPropStatus = (jsxElement, parentKey, childKey) => {
527
+ const getNestedPropStatus = (jsxElement, ast, parentKey, childKey) => {
492
528
  const attr = jsxElement.attributes.find((a) => a.type !== 'JSXSpreadAttribute' &&
493
529
  a.name.type !== 'JSXNamespacedName' &&
494
530
  a.name.name === parentKey);
@@ -515,7 +551,7 @@ const getNestedPropStatus = (jsxElement, parentKey, childKey) => {
515
551
  }
516
552
  const propValue = prop.value;
517
553
  if (!(0, exports.isStaticValue)(propValue)) {
518
- return (0, exports.getComputedStatus)(propValue);
554
+ return (0, exports.getComputedStatus)(propValue, ast);
519
555
  }
520
556
  const codeValue = (0, exports.extractStaticValue)(propValue);
521
557
  if (!validateStyleValue(childKey, codeValue)) {
@@ -531,13 +567,13 @@ const computeEffectsForJsx = ({ ast, jsxElement, effects, }) => {
531
567
  keys: effect,
532
568
  }));
533
569
  };
534
- const computeSequenceOnlyPropsRecord = ({ jsxElement, keys, }) => {
535
- const allProps = getPropsStatus(jsxElement);
570
+ const computeSequenceOnlyPropsRecord = ({ jsxElement, ast, keys, }) => {
571
+ const allProps = getPropsStatus(jsxElement, ast);
536
572
  const filteredProps = {};
537
573
  for (const key of keys) {
538
574
  const dotIndex = key.indexOf('.');
539
575
  if (dotIndex !== -1) {
540
- filteredProps[key] = getNestedPropStatus(jsxElement, key.slice(0, dotIndex), key.slice(dotIndex + 1));
576
+ filteredProps[key] = getNestedPropStatus(jsxElement, ast, key.slice(0, dotIndex), key.slice(dotIndex + 1));
541
577
  }
542
578
  else if (key in allProps) {
543
579
  filteredProps[key] = allProps[key];
@@ -554,7 +590,7 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, keys, e
554
590
  if (!jsxElement) {
555
591
  throw new jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError();
556
592
  }
557
- const filteredProps = computeSequenceOnlyPropsRecord({ jsxElement, keys });
593
+ const filteredProps = computeSequenceOnlyPropsRecord({ jsxElement, ast, keys });
558
594
  const effectsStatuses = computeEffectsForJsx({ ast, jsxElement, effects });
559
595
  return {
560
596
  canUpdate: true,
@@ -0,0 +1,7 @@
1
+ import { type DownloadRemoteAssetRequest, type DownloadRemoteAssetResponse, type ImageFileType } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const getRemoteAssetFilename: ({ fileType, url, }: {
4
+ fileType: ImageFileType;
5
+ url: URL;
6
+ }) => string;
7
+ export declare const downloadRemoteAssetHandler: ApiHandler<DownloadRemoteAssetRequest, DownloadRemoteAssetResponse>;