@remotion/studio-server 4.0.471 → 4.0.473

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/codemods/add-effect.d.ts +11 -0
  2. package/dist/codemods/add-effect.js +14 -52
  3. package/dist/codemods/effect-param-expression.d.ts +15 -0
  4. package/dist/codemods/effect-param-expression.js +131 -0
  5. package/dist/codemods/format-file-content.js +1 -1
  6. package/dist/codemods/parse-ast.js +4 -1
  7. package/dist/codemods/paste-effects.d.ts +15 -0
  8. package/dist/codemods/paste-effects.js +147 -0
  9. package/dist/codemods/recast-mods.js +178 -31
  10. package/dist/codemods/reorder-sequence.d.ts +14 -0
  11. package/dist/codemods/reorder-sequence.js +109 -0
  12. package/dist/codemods/update-effect-props/update-effect-props.d.ts +7 -0
  13. package/dist/codemods/update-effect-props/update-effect-props.js +64 -16
  14. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +1 -1
  15. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +7 -55
  16. package/dist/codemods/update-keyframes/update-keyframes.d.ts +24 -6
  17. package/dist/codemods/update-keyframes/update-keyframes.js +279 -16
  18. package/dist/helpers/get-ast-node-path.js +6 -1
  19. package/dist/helpers/import-agnostic-node-path.d.ts +10 -0
  20. package/dist/helpers/import-agnostic-node-path.js +154 -0
  21. package/dist/helpers/imports.d.ts +16 -0
  22. package/dist/helpers/imports.js +145 -0
  23. package/dist/helpers/resolve-composition-component.js +133 -51
  24. package/dist/preview-server/api-routes.js +16 -0
  25. package/dist/preview-server/routes/add-effect-keyframe.js +2 -0
  26. package/dist/preview-server/routes/add-sequence-keyframe.js +1 -0
  27. package/dist/preview-server/routes/apply-codemod.js +18 -0
  28. package/dist/preview-server/routes/can-update-effect-props.d.ts +3 -2
  29. package/dist/preview-server/routes/can-update-effect-props.js +78 -8
  30. package/dist/preview-server/routes/can-update-sequence-props.d.ts +1 -1
  31. package/dist/preview-server/routes/can-update-sequence-props.js +82 -43
  32. package/dist/preview-server/routes/delete-keyframes.js +1 -0
  33. package/dist/preview-server/routes/download-remote-asset.d.ts +7 -0
  34. package/dist/preview-server/routes/download-remote-asset.js +267 -0
  35. package/dist/preview-server/routes/insert-jsx-element.js +26 -0
  36. package/dist/preview-server/routes/log-studio-error.d.ts +3 -0
  37. package/dist/preview-server/routes/log-studio-error.js +58 -0
  38. package/dist/preview-server/routes/move-keyframes.d.ts +7 -0
  39. package/dist/preview-server/routes/move-keyframes.js +242 -0
  40. package/dist/preview-server/routes/paste-effects.d.ts +3 -0
  41. package/dist/preview-server/routes/paste-effects.js +78 -0
  42. package/dist/preview-server/routes/rename-static-file.d.ts +3 -0
  43. package/dist/preview-server/routes/rename-static-file.js +53 -0
  44. package/dist/preview-server/routes/reorder-sequence.d.ts +3 -0
  45. package/dist/preview-server/routes/reorder-sequence.js +67 -0
  46. package/dist/preview-server/routes/save-effect-props.js +25 -9
  47. package/dist/preview-server/routes/save-sequence-props.js +2 -34
  48. package/dist/preview-server/routes/update-effect-keyframe-settings.d.ts +3 -0
  49. package/dist/preview-server/routes/update-effect-keyframe-settings.js +90 -0
  50. package/dist/preview-server/routes/update-sequence-keyframe-settings.d.ts +3 -0
  51. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +85 -0
  52. package/dist/preview-server/undo-stack.d.ts +9 -1
  53. package/package.json +6 -6
@@ -8,7 +8,7 @@ const applyCodemod = ({ file, codeMod, }) => {
8
8
  return (0, apply_visual_control_1.applyVisualControl)({ file, transformation: codeMod, changesMade });
9
9
  }
10
10
  const body = file.program.body.map((node) => {
11
- return mapAll(node, codeMod, changesMade);
11
+ return mapAll(node, codeMod, changesMade, null);
12
12
  });
13
13
  return {
14
14
  newAst: {
@@ -22,9 +22,9 @@ const applyCodemod = ({ file, codeMod, }) => {
22
22
  };
23
23
  };
24
24
  exports.applyCodemod = applyCodemod;
25
- const mapAll = (node, transformation, changesMade) => {
25
+ const mapAll = (node, transformation, changesMade, parentFolderName) => {
26
26
  if (isRecognizedType(node)) {
27
- return mapRecognizedType(node, transformation, changesMade);
27
+ return mapRecognizedType(node, transformation, changesMade, parentFolderName);
28
28
  }
29
29
  return node;
30
30
  };
@@ -40,33 +40,33 @@ const isRecognizedType = (t) => {
40
40
  t.type === 'ExportNamedDeclaration' ||
41
41
  t.type === 'ExportDefaultDeclaration');
42
42
  };
43
- const mapVariableDeclarator = (variableDeclarator, transformation, changesMade) => {
43
+ const mapVariableDeclarator = (variableDeclarator, transformation, changesMade, parentFolderName) => {
44
44
  return {
45
45
  ...variableDeclarator,
46
46
  init: variableDeclarator.init
47
- ? mapAll(variableDeclarator.init, transformation, changesMade)
47
+ ? mapAll(variableDeclarator.init, transformation, changesMade, parentFolderName)
48
48
  : variableDeclarator.init,
49
49
  };
50
50
  };
51
- const mapBlockStatement = (blockStatement, transformation, changesMade) => {
51
+ const mapBlockStatement = (blockStatement, transformation, changesMade, parentFolderName) => {
52
52
  return {
53
53
  ...blockStatement,
54
54
  body: blockStatement.body.map((a) => {
55
- return mapAll(a, transformation, changesMade);
55
+ return mapAll(a, transformation, changesMade, parentFolderName);
56
56
  }),
57
57
  };
58
58
  };
59
- const mapReturnStatement = (statement, transformation, changesMade) => {
59
+ const mapReturnStatement = (statement, transformation, changesMade, parentFolderName) => {
60
60
  if (!statement.argument) {
61
61
  return statement;
62
62
  }
63
- const replacement = transformLoneJsxElement(statement.argument, transformation, changesMade);
63
+ const replacement = transformLoneJsxElement(statement.argument, transformation, changesMade, parentFolderName);
64
64
  if (replacement !== null) {
65
65
  return { ...statement, argument: replacement };
66
66
  }
67
67
  return {
68
68
  ...statement,
69
- argument: mapAll(statement.argument, transformation, changesMade),
69
+ argument: mapAll(statement.argument, transformation, changesMade, parentFolderName),
70
70
  };
71
71
  };
72
72
  const nullLiteral = () => ({ type: 'NullLiteral' });
@@ -86,40 +86,68 @@ const wrapInJsxFragment = (children) => ({
86
86
  type: 'JSXFragment',
87
87
  openingFragment: { type: 'JSXOpeningFragment' },
88
88
  closingFragment: { type: 'JSXClosingFragment' },
89
- children: children.map(stripParenthesizedExtra),
89
+ children: children.map((child) => {
90
+ if (child.type === 'JSXElement' || child.type === 'JSXFragment') {
91
+ return stripParenthesizedExtra(child);
92
+ }
93
+ return child;
94
+ }),
90
95
  });
96
+ const isJsxExpression = (child) => {
97
+ return child.type === 'JSXElement' || child.type === 'JSXFragment';
98
+ };
99
+ const isMeaningfulJsxChild = (child) => {
100
+ return child.type !== 'JSXText' || child.value.trim() !== '';
101
+ };
91
102
  // When a <Composition> JSX element appears in a position where it cannot
92
103
  // simply be removed from a parent's children list (e.g. as the sole return
93
104
  // value of a wrapper component or as the concise body of an arrow function),
94
105
  // we still want delete/rename/duplicate codemods to work. This helper detects
95
106
  // that case and produces a structurally-valid replacement expression.
96
- const transformLoneJsxElement = (expression, transformation, changesMade) => {
107
+ const transformLoneJsxElement = (expression, transformation, changesMade, parentFolderName) => {
97
108
  if (expression.type !== 'JSXElement') {
98
109
  return null;
99
110
  }
100
111
  const compId = getCompositionIdFromJSXElement(expression);
112
+ const folderName = getFolderNameFromJSXElement(expression);
101
113
  if (compId === null) {
102
- return null;
114
+ const isFolderMatch = folderName !== null &&
115
+ ((transformation.type === 'delete-folder' &&
116
+ folderName === transformation.folderName &&
117
+ parentFolderName === transformation.parentName) ||
118
+ (transformation.type === 'rename-folder' &&
119
+ folderName === transformation.folderName &&
120
+ parentFolderName === transformation.parentName));
121
+ if (!isFolderMatch) {
122
+ return null;
123
+ }
103
124
  }
104
125
  const isMatch = (transformation.type === 'delete-composition' &&
105
126
  compId === transformation.idToDelete) ||
106
127
  (transformation.type === 'rename-composition' &&
107
128
  compId === transformation.idToRename) ||
108
129
  (transformation.type === 'duplicate-composition' &&
109
- compId === transformation.idToDuplicate);
130
+ compId === transformation.idToDuplicate) ||
131
+ (transformation.type === 'delete-folder' &&
132
+ folderName === transformation.folderName &&
133
+ parentFolderName === transformation.parentName) ||
134
+ (transformation.type === 'rename-folder' &&
135
+ folderName === transformation.folderName &&
136
+ parentFolderName === transformation.parentName);
110
137
  if (!isMatch) {
111
138
  return null;
112
139
  }
113
- const transformed = mapJsxChild(expression, transformation, changesMade);
114
- if (transformed.length === 0) {
140
+ const transformed = mapJsxChild(expression, transformation, changesMade, parentFolderName);
141
+ const meaningful = transformed.filter(isMeaningfulJsxChild);
142
+ if (meaningful.length === 0) {
115
143
  return nullLiteral();
116
144
  }
117
- if (transformed.length === 1) {
118
- return transformed[0];
145
+ if (meaningful.length === 1 && isJsxExpression(meaningful[0])) {
146
+ return meaningful[0];
119
147
  }
120
148
  return wrapInJsxFragment(transformed);
121
149
  };
122
- const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade) => {
150
+ const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade, parentFolderName) => {
123
151
  return {
124
152
  ...jsxFragment,
125
153
  children: jsxFragment.children
@@ -127,13 +155,17 @@ const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade) => {
127
155
  if (c.type !== 'JSXElement') {
128
156
  return c;
129
157
  }
130
- return mapJsxChild(c, transformation, changesMade);
158
+ return mapJsxChild(c, transformation, changesMade, parentFolderName);
131
159
  })
132
160
  .flat(1),
133
161
  };
134
162
  };
135
- const mapJsxChild = (c, transformation, changesMade) => {
163
+ const getChildFolderParentName = ({ folderName, parentFolderName, }) => {
164
+ return [parentFolderName, folderName].filter(Boolean).join('/');
165
+ };
166
+ const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
136
167
  const compId = getCompositionIdFromJSXElement(c);
168
+ const folderName = getFolderNameFromJSXElement(c);
137
169
  if (transformation === null) {
138
170
  return [c];
139
171
  }
@@ -175,17 +207,39 @@ const mapJsxChild = (c, transformation, changesMade) => {
175
207
  });
176
208
  return [];
177
209
  }
178
- return [mapAll(c, transformation, changesMade)];
210
+ if (transformation.type === 'rename-folder' &&
211
+ folderName === transformation.folderName &&
212
+ parentFolderName === transformation.parentName) {
213
+ return [
214
+ changeFolderName({
215
+ jsxElement: c,
216
+ newFolderName: transformation.newName,
217
+ changesMade,
218
+ }),
219
+ ];
220
+ }
221
+ if (transformation.type === 'delete-folder' &&
222
+ folderName === transformation.folderName &&
223
+ parentFolderName === transformation.parentName) {
224
+ changesMade.push({
225
+ description: 'Deleted folder',
226
+ });
227
+ return c.children;
228
+ }
229
+ const childParentFolderName = folderName
230
+ ? getChildFolderParentName({ folderName, parentFolderName })
231
+ : parentFolderName;
232
+ return [mapAll(c, transformation, changesMade, childParentFolderName)];
179
233
  };
180
- const mapRecognizedType = (expression, transformation, changesMade) => {
234
+ const mapRecognizedType = (expression, transformation, changesMade, parentFolderName) => {
181
235
  if (expression.type === 'JSXFragment' || expression.type === 'JSXElement') {
182
- return mapJsxElementOrFragment(expression, transformation, changesMade);
236
+ return mapJsxElementOrFragment(expression, transformation, changesMade, parentFolderName);
183
237
  }
184
238
  if (expression.type === 'ArrowFunctionExpression' ||
185
239
  expression.type === 'FunctionExpression') {
186
240
  if (expression.type === 'ArrowFunctionExpression' &&
187
241
  expression.body.type === 'JSXElement') {
188
- const replacement = transformLoneJsxElement(expression.body, transformation, changesMade);
242
+ const replacement = transformLoneJsxElement(expression.body, transformation, changesMade, parentFolderName);
189
243
  if (replacement !== null) {
190
244
  return {
191
245
  ...expression,
@@ -195,19 +249,19 @@ const mapRecognizedType = (expression, transformation, changesMade) => {
195
249
  }
196
250
  return {
197
251
  ...expression,
198
- body: mapAll(expression.body, transformation, changesMade),
252
+ body: mapAll(expression.body, transformation, changesMade, parentFolderName),
199
253
  };
200
254
  }
201
255
  if (expression.type === 'VariableDeclaration') {
202
256
  const declarations = expression.declarations.map((d) => {
203
- return mapVariableDeclarator(d, transformation, changesMade);
257
+ return mapVariableDeclarator(d, transformation, changesMade, parentFolderName);
204
258
  });
205
259
  return { ...expression, declarations };
206
260
  }
207
261
  if (expression.type === 'FunctionDeclaration') {
208
262
  return {
209
263
  ...expression,
210
- body: mapBlockStatement(expression.body, transformation, changesMade),
264
+ body: mapBlockStatement(expression.body, transformation, changesMade, parentFolderName),
211
265
  };
212
266
  }
213
267
  if (expression.type === 'ExportNamedDeclaration' ||
@@ -217,14 +271,14 @@ const mapRecognizedType = (expression, transformation, changesMade) => {
217
271
  }
218
272
  return {
219
273
  ...expression,
220
- declaration: mapAll(expression.declaration, transformation, changesMade),
274
+ declaration: mapAll(expression.declaration, transformation, changesMade, parentFolderName),
221
275
  };
222
276
  }
223
277
  if (expression.type === 'ReturnStatement') {
224
- return mapReturnStatement(expression, transformation, changesMade);
278
+ return mapReturnStatement(expression, transformation, changesMade, parentFolderName);
225
279
  }
226
280
  if (expression.type === 'BlockStatement') {
227
- return mapBlockStatement(expression, transformation, changesMade);
281
+ return mapBlockStatement(expression, transformation, changesMade, parentFolderName);
228
282
  }
229
283
  return expression;
230
284
  };
@@ -266,6 +320,99 @@ const getCompositionIdFromJSXElement = (jsxElement) => {
266
320
  .filter(Boolean);
267
321
  return id[0];
268
322
  };
323
+ const getFolderNameFromJSXElement = (jsxElement) => {
324
+ if (jsxElement.type !== 'JSXElement') {
325
+ return null;
326
+ }
327
+ const { openingElement } = jsxElement;
328
+ const { name } = openingElement;
329
+ if (name.type !== 'JSXIdentifier') {
330
+ return null;
331
+ }
332
+ if (name.name !== 'Folder') {
333
+ return null;
334
+ }
335
+ const folderName = openingElement.attributes
336
+ .map((attribute) => {
337
+ if (attribute.type === 'JSXSpreadAttribute') {
338
+ return null;
339
+ }
340
+ if (attribute.name.type === 'JSXNamespacedName') {
341
+ return null;
342
+ }
343
+ if (attribute.name.name !== 'name') {
344
+ return null;
345
+ }
346
+ if (!attribute.value) {
347
+ return null;
348
+ }
349
+ if (attribute.value.type === 'StringLiteral') {
350
+ return attribute.value.value;
351
+ }
352
+ if (attribute.value.type === 'JSXExpressionContainer' &&
353
+ attribute.value.expression.type === 'StringLiteral') {
354
+ return attribute.value.expression.value;
355
+ }
356
+ return null;
357
+ })
358
+ .filter(Boolean);
359
+ return folderName[0];
360
+ };
361
+ const changeFolderName = ({ jsxElement, newFolderName, changesMade, }) => {
362
+ const { openingElement } = jsxElement;
363
+ const { name } = openingElement;
364
+ if (name.type !== 'JSXIdentifier') {
365
+ return jsxElement;
366
+ }
367
+ if (name.name !== 'Folder') {
368
+ return jsxElement;
369
+ }
370
+ const attributes = openingElement.attributes.map((attribute) => {
371
+ if (attribute.type === 'JSXSpreadAttribute') {
372
+ return attribute;
373
+ }
374
+ if (attribute.name.type === 'JSXNamespacedName') {
375
+ return attribute;
376
+ }
377
+ if (attribute.name.name === 'name' &&
378
+ attribute.value &&
379
+ attribute.value.type === 'StringLiteral') {
380
+ changesMade.push({
381
+ description: 'Replaced folder name',
382
+ });
383
+ return {
384
+ ...attribute,
385
+ value: { ...attribute.value, value: newFolderName },
386
+ };
387
+ }
388
+ if (attribute.name.name === 'name' &&
389
+ attribute.value &&
390
+ attribute.value.type === 'JSXExpressionContainer' &&
391
+ attribute.value.expression.type === 'StringLiteral') {
392
+ changesMade.push({
393
+ description: 'Replaced folder name',
394
+ });
395
+ return {
396
+ ...attribute,
397
+ value: {
398
+ ...attribute.value,
399
+ expression: {
400
+ ...attribute.value.expression,
401
+ value: newFolderName,
402
+ },
403
+ },
404
+ };
405
+ }
406
+ return attribute;
407
+ });
408
+ return {
409
+ ...jsxElement,
410
+ openingElement: {
411
+ ...jsxElement.openingElement,
412
+ attributes,
413
+ },
414
+ };
415
+ };
269
416
  const changeComposition = ({ jsxElement, newCompositionId, newCompositionFps, newCompositionDurationInFrames, newCompositionHeight, newCompositionWidth, changesMade, newTagToUse, }) => {
270
417
  const { openingElement } = jsxElement;
271
418
  const { name } = openingElement;
@@ -0,0 +1,14 @@
1
+ import type { ReorderSequencePosition } from '@remotion/studio-shared';
2
+ import type { SequenceNodePath } from 'remotion';
3
+ export declare const reorderSequence: ({ input, sourceNodePath, targetNodePath, position, prettierConfigOverride, }: {
4
+ input: string;
5
+ sourceNodePath: SequenceNodePath;
6
+ targetNodePath: SequenceNodePath;
7
+ position: ReorderSequencePosition;
8
+ prettierConfigOverride?: Record<string, unknown> | null | undefined;
9
+ }) => Promise<{
10
+ output: string;
11
+ formatted: boolean;
12
+ sequenceLabel: string;
13
+ logLine: number;
14
+ }>;
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.reorderSequence = void 0;
37
+ const recast = __importStar(require("recast"));
38
+ const delete_jsx_node_1 = require("./delete-jsx-node");
39
+ const format_file_content_1 = require("./format-file-content");
40
+ const parse_ast_1 = require("./parse-ast");
41
+ const { namedTypes } = recast.types;
42
+ const getJsxChildrenParent = (path) => {
43
+ var _a;
44
+ const parent = (_a = path.parentPath) === null || _a === void 0 ? void 0 : _a.node;
45
+ if (!parent) {
46
+ return null;
47
+ }
48
+ if (namedTypes.JSXElement.check(parent)) {
49
+ return parent;
50
+ }
51
+ if (namedTypes.JSXFragment.check(parent)) {
52
+ return parent;
53
+ }
54
+ return null;
55
+ };
56
+ const reorderSequence = async ({ input, sourceNodePath, targetNodePath, position, prettierConfigOverride, }) => {
57
+ var _a, _b;
58
+ var _c, _d;
59
+ const ast = (0, parse_ast_1.parseAst)(input);
60
+ const sourcePath = (0, delete_jsx_node_1.findJsxElementPathForDeletion)(ast, sourceNodePath);
61
+ if (!sourcePath) {
62
+ throw new Error('Could not find a JSX element at the source location to reorder sequence');
63
+ }
64
+ const targetPath = (0, delete_jsx_node_1.findJsxElementPathForDeletion)(ast, targetNodePath);
65
+ if (!targetPath) {
66
+ throw new Error('Could not find a JSX element at the target location to reorder sequence');
67
+ }
68
+ const sourceParent = getJsxChildrenParent(sourcePath);
69
+ const targetParent = getJsxChildrenParent(targetPath);
70
+ if (!sourceParent || !targetParent || sourceParent !== targetParent) {
71
+ throw new Error('Cannot reorder sequence: source and target are not JSX siblings');
72
+ }
73
+ const sourceElement = sourcePath.node;
74
+ const targetElement = targetPath.node;
75
+ if (sourceElement === targetElement) {
76
+ throw new Error('Cannot reorder sequence: source and target are identical');
77
+ }
78
+ const { children } = sourceParent;
79
+ const sourceIndex = children.indexOf(sourceElement);
80
+ const targetIndex = children.indexOf(targetElement);
81
+ if (sourceIndex === -1 || targetIndex === -1) {
82
+ throw new Error('Cannot reorder sequence: JSX sibling was not found');
83
+ }
84
+ const sequenceLabel = (0, delete_jsx_node_1.getJsxElementTagLabel)(sourceElement);
85
+ const logLine = (_d = (_c = (_a = sourceElement.openingElement.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _c !== void 0 ? _c : (_b = sourceElement.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _d !== void 0 ? _d : 1;
86
+ const [moved] = children.splice(sourceIndex, 1);
87
+ if (!moved) {
88
+ throw new Error('Cannot reorder sequence: source sequence was not found');
89
+ }
90
+ const targetIndexAfterRemoval = children.indexOf(targetElement);
91
+ if (targetIndexAfterRemoval === -1) {
92
+ throw new Error('Cannot reorder sequence: target sequence was not found');
93
+ }
94
+ children.splice(position === 'before'
95
+ ? targetIndexAfterRemoval
96
+ : targetIndexAfterRemoval + 1, 0, moved);
97
+ const finalFile = (0, parse_ast_1.serializeAst)(ast);
98
+ const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
99
+ input: finalFile,
100
+ prettierConfigOverride,
101
+ });
102
+ return {
103
+ output,
104
+ formatted,
105
+ sequenceLabel,
106
+ logLine,
107
+ };
108
+ };
109
+ exports.reorderSequence = reorderSequence;
@@ -1,14 +1,20 @@
1
1
  import type { ArrayExpression, CallExpression, JSXAttribute } from '@babel/types';
2
+ import type { EffectClipboardParam } from '@remotion/studio-shared';
2
3
  import type { SequenceNodePath, SequenceSchema } from 'remotion';
3
4
  export type EffectPropUpdate = {
4
5
  key: string;
5
6
  value: unknown;
6
7
  defaultValue: unknown | null;
8
+ } | {
9
+ key: string;
10
+ effectParam: EffectClipboardParam;
11
+ defaultValue: unknown | null;
7
12
  };
8
13
  export type UpdateEffectPropsResult = {
9
14
  output: string;
10
15
  formatted: boolean;
11
16
  oldValueString: string;
17
+ newValueString: string;
12
18
  logLine: number;
13
19
  effectCallee: string;
14
20
  removedProps: PropDelta[];
@@ -47,6 +53,7 @@ export declare const updateEffectPropsAst: ({ input, sequenceNodePath, effectInd
47
53
  }) => {
48
54
  serialized: string;
49
55
  oldValueString: string;
56
+ newValueString: string;
50
57
  logLine: number;
51
58
  effectCallee: string;
52
59
  removedProps: PropDelta[];
@@ -34,23 +34,16 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.updateEffectProps = exports.updateEffectPropsAst = exports.findEffectCallExpression = exports.enumerateEffectArrayElements = exports.findEffectsAttr = void 0;
37
- const studio_shared_1 = require("@remotion/studio-shared");
38
37
  const recast = __importStar(require("recast"));
39
38
  const no_react_1 = require("remotion/no-react");
39
+ const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
40
40
  const can_update_sequence_props_1 = require("../../preview-server/routes/can-update-sequence-props");
41
+ const effect_param_expression_1 = require("../effect-param-expression");
41
42
  const format_file_content_1 = require("../format-file-content");
42
43
  const parse_ast_1 = require("../parse-ast");
44
+ const ensure_imports_and_frame_hook_1 = require("../update-keyframes/ensure-imports-and-frame-hook");
45
+ const update_nested_prop_1 = require("../update-nested-prop");
43
46
  const b = recast.types.builders;
44
- const parseValueExpression = (value) => {
45
- const code = `a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: value, enumPaths: [] })}`;
46
- const ast = (0, parse_ast_1.parseAst)(code);
47
- const stmt = ast.program.body[0];
48
- if (stmt.type !== 'ExpressionStatement' ||
49
- stmt.expression.type !== 'AssignmentExpression') {
50
- throw new Error('Failed to parse effect prop value expression');
51
- }
52
- return stmt.expression.right;
53
- };
54
47
  const findEffectsAttr = (attrs) => {
55
48
  for (const attr of attrs) {
56
49
  if (attr.type !== 'JSXAttribute') {
@@ -138,6 +131,47 @@ const printObjectPropertyValue = (prop) => recast
138
131
  .code.replace(/[\n\r\t]+/g, ' ')
139
132
  .replace(/,(\s*[}\]])/g, '$1')
140
133
  .trim();
134
+ const updateHasEffectParam = (update) => 'effectParam' in update;
135
+ const getStaticUpdateValue = (update) => {
136
+ if (updateHasEffectParam(update)) {
137
+ return update.effectParam.type === 'static'
138
+ ? update.effectParam.value
139
+ : null;
140
+ }
141
+ return update.value;
142
+ };
143
+ const ensureClipboardParamImports = ({ ast, sequenceNodePath, param, }) => {
144
+ var _a;
145
+ const requiredImports = (0, effect_param_expression_1.getRequiredRemotionImportsForEffectParams)([param]);
146
+ const remotionLocalNames = (0, effect_param_expression_1.ensureRemotionImportLocalNames)({
147
+ ast,
148
+ requiredImports,
149
+ });
150
+ if (requiredImports.has('useCurrentFrame')) {
151
+ const targetJsxPath = (0, get_ast_node_path_1.getAstNodePath)(ast, sequenceNodePath);
152
+ if (targetJsxPath) {
153
+ const fnPath = (0, ensure_imports_and_frame_hook_1.findEnclosingFunctionPath)(targetJsxPath);
154
+ if (fnPath) {
155
+ (0, ensure_imports_and_frame_hook_1.ensureUseCurrentFrameHook)(fnPath, (_a = remotionLocalNames.useCurrentFrame) !== null && _a !== void 0 ? _a : 'useCurrentFrame');
156
+ }
157
+ }
158
+ }
159
+ return remotionLocalNames;
160
+ };
161
+ const makeUpdateValueExpression = ({ ast, sequenceNodePath, update, }) => {
162
+ if (!updateHasEffectParam(update)) {
163
+ return (0, update_nested_prop_1.parseValueExpression)(update.value);
164
+ }
165
+ const remotionLocalNames = ensureClipboardParamImports({
166
+ ast,
167
+ sequenceNodePath,
168
+ param: update.effectParam,
169
+ });
170
+ return (0, effect_param_expression_1.makeParamExpression)({
171
+ param: update.effectParam,
172
+ remotionLocalNames,
173
+ });
174
+ };
141
175
  const removeObjectProperty = ({ objExpr, propertyName, }) => {
142
176
  const { propIndex, prop } = findObjectProperty(objExpr, propertyName);
143
177
  if (!prop || propIndex === -1) {
@@ -170,7 +204,8 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
170
204
  throw new Error(`Cannot update effect prop: ${found.reason}`);
171
205
  }
172
206
  const { call, callee: effectCallee } = found;
173
- const isDefault = update.defaultValue !== null &&
207
+ const isDefault = !updateHasEffectParam(update) &&
208
+ update.defaultValue !== null &&
174
209
  JSON.stringify(update.value) === JSON.stringify(update.defaultValue);
175
210
  let objExpr;
176
211
  if (call.arguments.length === 0) {
@@ -178,6 +213,7 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
178
213
  return {
179
214
  serialized: (0, parse_ast_1.serializeAst)(ast),
180
215
  oldValueString: '',
216
+ newValueString: JSON.stringify(update.defaultValue),
181
217
  logLine: (_g = (_f = (_a = call.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _f !== void 0 ? _f : (_b = jsx.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _g !== void 0 ? _g : 1,
182
218
  effectCallee,
183
219
  removedProps: [],
@@ -201,7 +237,9 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
201
237
  else if (update.defaultValue !== null) {
202
238
  oldValueString = JSON.stringify(update.defaultValue);
203
239
  }
240
+ let newValueString = '';
204
241
  if (isDefault) {
242
+ newValueString = JSON.stringify(update.defaultValue);
205
243
  if (prop) {
206
244
  const idx = objExpr.properties.indexOf(prop);
207
245
  if (idx !== -1) {
@@ -210,7 +248,12 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
210
248
  }
211
249
  }
212
250
  else {
213
- const newValueExpr = parseValueExpression(update.value);
251
+ const newValueExpr = makeUpdateValueExpression({
252
+ ast,
253
+ sequenceNodePath,
254
+ update,
255
+ });
256
+ newValueString = recast.print(newValueExpr).code;
214
257
  if (prop) {
215
258
  prop.value = newValueExpr;
216
259
  }
@@ -219,11 +262,14 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
219
262
  }
220
263
  }
221
264
  const fieldSchema = schema[update.key];
222
- if (fieldSchema && fieldSchema.type === 'enum') {
265
+ const staticUpdateValue = getStaticUpdateValue(update);
266
+ if (fieldSchema &&
267
+ fieldSchema.type === 'enum' &&
268
+ staticUpdateValue !== null) {
223
269
  const propsToDelete = no_react_1.NoReactInternals.findPropsToDelete({
224
270
  schema,
225
271
  key: update.key,
226
- value: update.value,
272
+ value: staticUpdateValue,
227
273
  });
228
274
  for (const propToDelete of propsToDelete) {
229
275
  const removed = removeObjectProperty({
@@ -239,6 +285,7 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
239
285
  return {
240
286
  serialized: (0, parse_ast_1.serializeAst)(ast),
241
287
  oldValueString,
288
+ newValueString,
242
289
  logLine,
243
290
  effectCallee,
244
291
  removedProps,
@@ -246,7 +293,7 @@ const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, sc
246
293
  };
247
294
  exports.updateEffectPropsAst = updateEffectPropsAst;
248
295
  const updateEffectProps = async ({ input, sequenceNodePath, effectIndex, update, schema, prettierConfigOverride, }) => {
249
- const { serialized, oldValueString, logLine, effectCallee, removedProps } = (0, exports.updateEffectPropsAst)({
296
+ const { serialized, oldValueString, newValueString, logLine, effectCallee, removedProps, } = (0, exports.updateEffectPropsAst)({
250
297
  input,
251
298
  sequenceNodePath,
252
299
  effectIndex,
@@ -260,6 +307,7 @@ const updateEffectProps = async ({ input, sequenceNodePath, effectIndex, update,
260
307
  return {
261
308
  output,
262
309
  oldValueString,
310
+ newValueString,
263
311
  formatted,
264
312
  logLine,
265
313
  effectCallee,
@@ -1,4 +1,4 @@
1
1
  import type { File } from '@babel/types';
2
2
  export declare const findEnclosingFunctionPath: (path: import("ast-types/lib/node-path").NodePath<N, V>) => import("ast-types/lib/node-path").NodePath<N, V> | null;
3
3
  export declare const ensureRemotionImports: (ast: File, names: ReadonlySet<string>) => void;
4
- export declare const ensureUseCurrentFrameHook: (functionPath: import("ast-types/lib/node-path").NodePath<N, V>) => void;
4
+ export declare const ensureUseCurrentFrameHook: (functionPath: import("ast-types/lib/node-path").NodePath<N, V>, hookName?: string) => void;