@remotion/studio-server 4.0.485 → 4.0.487

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.
@@ -94,6 +94,14 @@ const parseAndApplyCodemod = ({ input, codeMod, }) => {
94
94
  localName: codeMod.componentName,
95
95
  });
96
96
  }
97
+ if (codeMod.type === 'new-folder') {
98
+ (0, imports_1.ensureNamedImport)({
99
+ ast: newAst,
100
+ importedName: 'Folder',
101
+ sourcePath: 'remotion',
102
+ localName: 'Folder',
103
+ });
104
+ }
97
105
  const output = (0, parse_ast_1.serializeAst)(newAst);
98
106
  return { changesMade, newContents: output };
99
107
  };
@@ -36,12 +36,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.applyCodemod = void 0;
37
37
  const recast = __importStar(require("recast"));
38
38
  const apply_visual_control_1 = require("./apply-visual-control");
39
+ const delete_jsx_node_1 = require("./delete-jsx-node");
39
40
  const b = recast.types.builders;
40
41
  const applyCodemod = ({ file, codeMod, }) => {
41
42
  const changesMade = [];
42
43
  if (codeMod.type === 'apply-visual-control') {
43
44
  return (0, apply_visual_control_1.applyVisualControl)({ file, transformation: codeMod, changesMade });
44
45
  }
46
+ if (codeMod.type === 'move-composition-to-folder') {
47
+ return moveCompositionToFolder({
48
+ file,
49
+ transformation: codeMod,
50
+ changesMade,
51
+ });
52
+ }
45
53
  const body = file.program.body.map((node) => {
46
54
  return mapAll(node, codeMod, changesMade, null);
47
55
  });
@@ -104,6 +112,15 @@ const mapReturnStatement = (statement, transformation, changesMade, parentFolder
104
112
  argument: addNewCompositionToRootJsx(statement.argument, transformation, changesMade),
105
113
  };
106
114
  }
115
+ if (transformation.type === 'new-folder' &&
116
+ transformation.parentName === null &&
117
+ (statement.argument.type === 'JSXElement' ||
118
+ statement.argument.type === 'JSXFragment')) {
119
+ return {
120
+ ...statement,
121
+ argument: addNewFolderToRootJsx(statement.argument, transformation, changesMade),
122
+ };
123
+ }
107
124
  const replacement = transformLoneJsxElement(statement.argument, transformation, changesMade, parentFolderName);
108
125
  if (replacement !== null) {
109
126
  return { ...statement, argument: replacement };
@@ -177,6 +194,19 @@ const newCompositionElement = (transformation) => {
177
194
  children: [],
178
195
  };
179
196
  };
197
+ const newFolderElement = (transformation) => {
198
+ return {
199
+ type: 'JSXElement',
200
+ openingElement: {
201
+ type: 'JSXOpeningElement',
202
+ name: jsxId('Folder'),
203
+ attributes: [jsxAttributeWithString('name', transformation.folderName)],
204
+ selfClosing: true,
205
+ },
206
+ closingElement: null,
207
+ children: [],
208
+ };
209
+ };
180
210
  const addNewCompositionToRootJsx = (root, transformation, changesMade) => {
181
211
  if (changesMade.length > 0) {
182
212
  return root;
@@ -192,6 +222,21 @@ const addNewCompositionToRootJsx = (root, transformation, changesMade) => {
192
222
  }
193
223
  return wrapInJsxFragment([root, newCompositionElement(transformation)]);
194
224
  };
225
+ const addNewFolderToRootJsx = (root, transformation, changesMade) => {
226
+ if (changesMade.length > 0) {
227
+ return root;
228
+ }
229
+ changesMade.push({
230
+ description: 'Added new folder',
231
+ });
232
+ if (root.type === 'JSXFragment') {
233
+ return {
234
+ ...root,
235
+ children: [...root.children, newFolderElement(transformation)],
236
+ };
237
+ }
238
+ return wrapInJsxFragment([root, newFolderElement(transformation)]);
239
+ };
195
240
  const addNewCompositionToFolder = (folderElement, transformation, changesMade) => {
196
241
  var _a;
197
242
  if (changesMade.length > 0) {
@@ -216,6 +261,146 @@ const addNewCompositionToFolder = (folderElement, transformation, changesMade) =
216
261
  ],
217
262
  };
218
263
  };
264
+ const addNewFolderToFolder = (folderElement, transformation, changesMade) => {
265
+ var _a;
266
+ if (changesMade.length > 0) {
267
+ return folderElement;
268
+ }
269
+ changesMade.push({
270
+ description: 'Added new folder',
271
+ });
272
+ return {
273
+ ...folderElement,
274
+ openingElement: {
275
+ ...folderElement.openingElement,
276
+ selfClosing: false,
277
+ },
278
+ closingElement: (_a = folderElement.closingElement) !== null && _a !== void 0 ? _a : {
279
+ type: 'JSXClosingElement',
280
+ name: folderElement.openingElement.name,
281
+ },
282
+ children: [...folderElement.children, newFolderElement(transformation)],
283
+ };
284
+ };
285
+ const getChildFolderParentName = ({ folderName, parentFolderName, }) => {
286
+ return [parentFolderName, folderName].filter(Boolean).join('/');
287
+ };
288
+ const appendCompositionToFolder = ({ compositionElement, folderElement, }) => {
289
+ var _a;
290
+ folderElement.openingElement.selfClosing = false;
291
+ folderElement.closingElement = (_a = folderElement.closingElement) !== null && _a !== void 0 ? _a : {
292
+ type: 'JSXClosingElement',
293
+ name: folderElement.openingElement.name,
294
+ };
295
+ folderElement.children.push(stripParenthesizedExtra(compositionElement));
296
+ };
297
+ const appendCompositionToRoot = ({ compositionElement, file, }) => {
298
+ let appended = false;
299
+ recast.types.visit(file, {
300
+ visitReturnStatement(astPath) {
301
+ if (appended) {
302
+ return false;
303
+ }
304
+ const { argument } = astPath.node;
305
+ if ((argument === null || argument === void 0 ? void 0 : argument.type) !== 'JSXFragment' && (argument === null || argument === void 0 ? void 0 : argument.type) !== 'JSXElement') {
306
+ this.traverse(astPath);
307
+ return undefined;
308
+ }
309
+ if (argument.type === 'JSXFragment') {
310
+ argument.children.push(stripParenthesizedExtra(compositionElement));
311
+ }
312
+ else {
313
+ astPath.node.argument = wrapInJsxFragment([
314
+ argument,
315
+ compositionElement,
316
+ ]);
317
+ }
318
+ appended = true;
319
+ return false;
320
+ },
321
+ });
322
+ if (!appended) {
323
+ throw new Error('Could not find a root JSX element');
324
+ }
325
+ };
326
+ const moveCompositionToFolder = ({ file, transformation, changesMade, }) => {
327
+ let sourcePath = null;
328
+ let sourceParentFolderName = null;
329
+ let sourceIsDirectJsxChild = false;
330
+ let targetFolder = null;
331
+ const folderStack = [];
332
+ const isDirectJsxChild = (astPath) => {
333
+ var _a;
334
+ const parent = (_a = astPath.parentPath) === null || _a === void 0 ? void 0 : _a.node;
335
+ return (((parent === null || parent === void 0 ? void 0 : parent.type) === 'JSXElement' || (parent === null || parent === void 0 ? void 0 : parent.type) === 'JSXFragment') &&
336
+ parent.children.includes(astPath.node));
337
+ };
338
+ const visitJsxElementWithFolderContext = (astPath) => {
339
+ const node = astPath.node;
340
+ const compositionId = getCompositionIdFromJSXElement(node);
341
+ if (compositionId === transformation.idToMove) {
342
+ sourcePath = astPath;
343
+ sourceParentFolderName = folderStack.join('/') || null;
344
+ sourceIsDirectJsxChild = isDirectJsxChild(astPath);
345
+ }
346
+ const folderName = getFolderNameFromJSXElement(node);
347
+ const parentName = folderStack.join('/') || null;
348
+ if (transformation.folderName !== null &&
349
+ folderName === transformation.folderName &&
350
+ parentName === transformation.parentName) {
351
+ targetFolder = node;
352
+ }
353
+ if (folderName) {
354
+ folderStack.push(folderName);
355
+ }
356
+ for (let i = 0; i < node.children.length; i++) {
357
+ if (node.children[i].type !== 'JSXElement') {
358
+ continue;
359
+ }
360
+ visitJsxElementWithFolderContext(astPath.get('children', i));
361
+ }
362
+ if (folderName) {
363
+ folderStack.pop();
364
+ }
365
+ };
366
+ recast.types.visit(file, {
367
+ visitJSXElement(astPath) {
368
+ visitJsxElementWithFolderContext(astPath);
369
+ return false;
370
+ },
371
+ });
372
+ if (!sourcePath) {
373
+ throw new Error(`Could not find composition "${transformation.idToMove}"`);
374
+ }
375
+ if (!sourceIsDirectJsxChild) {
376
+ throw new Error(`Cannot move composition "${transformation.idToMove}" because it is not a direct JSX child`);
377
+ }
378
+ if (transformation.folderName === null && sourceParentFolderName === null) {
379
+ return { newAst: file, changesMade };
380
+ }
381
+ if (transformation.folderName !== null && !targetFolder) {
382
+ const folderLabel = `${transformation.parentName ? `${transformation.parentName}/` : ''}${transformation.folderName}`;
383
+ throw new Error(`Could not find folder "${folderLabel}"`);
384
+ }
385
+ const compositionElement = sourcePath
386
+ .node;
387
+ (0, delete_jsx_node_1.deleteJsxElementAtPath)(sourcePath);
388
+ if (transformation.folderName === null) {
389
+ appendCompositionToRoot({ compositionElement, file });
390
+ changesMade.push({ description: 'Moved composition to root' });
391
+ }
392
+ else {
393
+ if (targetFolder === null) {
394
+ throw new Error('Could not find target folder');
395
+ }
396
+ appendCompositionToFolder({
397
+ compositionElement,
398
+ folderElement: targetFolder,
399
+ });
400
+ changesMade.push({ description: 'Moved composition into folder' });
401
+ }
402
+ return { newAst: file, changesMade };
403
+ };
219
404
  // When a <Composition> JSX element appears in a position where it cannot
220
405
  // simply be removed from a parent's children list (e.g. as the sole return
221
406
  // value of a wrapper component or as the concise body of an arrow function),
@@ -237,7 +422,10 @@ const transformLoneJsxElement = (expression, transformation, changesMade, parent
237
422
  parentFolderName === transformation.parentName) ||
238
423
  (transformation.type === 'new-composition' &&
239
424
  folderName === transformation.folderName &&
240
- parentFolderName === transformation.parentName));
425
+ parentFolderName === transformation.parentName) ||
426
+ (transformation.type === 'new-folder' &&
427
+ getChildFolderParentName({ folderName, parentFolderName }) ===
428
+ transformation.parentName));
241
429
  if (!isFolderMatch) {
242
430
  return null;
243
431
  }
@@ -256,7 +444,11 @@ const transformLoneJsxElement = (expression, transformation, changesMade, parent
256
444
  parentFolderName === transformation.parentName) ||
257
445
  (transformation.type === 'new-composition' &&
258
446
  folderName === transformation.folderName &&
259
- parentFolderName === transformation.parentName);
447
+ parentFolderName === transformation.parentName) ||
448
+ (transformation.type === 'new-folder' &&
449
+ folderName !== null &&
450
+ getChildFolderParentName({ folderName, parentFolderName }) ===
451
+ transformation.parentName);
260
452
  if (!isMatch) {
261
453
  return null;
262
454
  }
@@ -283,9 +475,6 @@ const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade, paren
283
475
  .flat(1),
284
476
  };
285
477
  };
286
- const getChildFolderParentName = ({ folderName, parentFolderName, }) => {
287
- return [parentFolderName, folderName].filter(Boolean).join('/');
288
- };
289
478
  const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
290
479
  const compId = getCompositionIdFromJSXElement(c);
291
480
  const folderName = getFolderNameFromJSXElement(c);
@@ -354,6 +543,12 @@ const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
354
543
  parentFolderName === transformation.parentName) {
355
544
  return [addNewCompositionToFolder(c, transformation, changesMade)];
356
545
  }
546
+ if (transformation.type === 'new-folder' &&
547
+ folderName !== null &&
548
+ getChildFolderParentName({ folderName, parentFolderName }) ===
549
+ transformation.parentName) {
550
+ return [addNewFolderToFolder(c, transformation, changesMade)];
551
+ }
357
552
  const childParentFolderName = folderName
358
553
  ? getChildFolderParentName({ folderName, parentFolderName })
359
554
  : parentFolderName;
@@ -374,6 +569,15 @@ const mapRecognizedType = (expression, transformation, changesMade, parentFolder
374
569
  body: addNewCompositionToRootJsx(expression.body, transformation, changesMade),
375
570
  };
376
571
  }
572
+ if (transformation.type === 'new-folder' &&
573
+ transformation.parentName === null &&
574
+ (expression.body.type === 'JSXElement' ||
575
+ expression.body.type === 'JSXFragment')) {
576
+ return {
577
+ ...expression,
578
+ body: addNewFolderToRootJsx(expression.body, transformation, changesMade),
579
+ };
580
+ }
377
581
  if (expression.type === 'ArrowFunctionExpression' &&
378
582
  expression.body.type === 'JSXElement') {
379
583
  const replacement = transformLoneJsxElement(expression.body, transformation, changesMade, parentFolderName);
@@ -37,6 +37,7 @@ exports.updateEffectKeyframes = exports.updateEffectKeyframesAst = exports.updat
37
37
  const studio_shared_1 = require("@remotion/studio-shared");
38
38
  const recast = __importStar(require("recast"));
39
39
  const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
40
+ const parse_keyframe_easing_expression_1 = require("../../helpers/parse-keyframe-easing-expression");
40
41
  const can_update_sequence_props_1 = require("../../preview-server/routes/can-update-sequence-props");
41
42
  const format_file_content_1 = require("../format-file-content");
42
43
  const parse_ast_1 = require("../parse-ast");
@@ -225,55 +226,7 @@ const setOptionsProperty = ({ options, propertyName, value, }) => {
225
226
  options.properties.push(b.objectProperty(b.identifier(propertyName), value));
226
227
  };
227
228
  const isLinearEasing = (easing) => easing.type === 'linear';
228
- const getKeyframeEasing = (node) => {
229
- if (node.type === 'TSAsExpression') {
230
- return getKeyframeEasing(node.expression);
231
- }
232
- if (node.type === 'MemberExpression' &&
233
- node.object.type === 'Identifier' &&
234
- node.object.name === 'Easing' &&
235
- node.property.type === 'Identifier' &&
236
- node.property.name === 'linear' &&
237
- node.computed === false) {
238
- return { type: 'linear' };
239
- }
240
- if (node.type !== 'CallExpression' ||
241
- node.callee.type !== 'MemberExpression' ||
242
- node.callee.object.type !== 'Identifier' ||
243
- node.callee.object.name !== 'Easing' ||
244
- node.callee.property.type !== 'Identifier' ||
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) {
261
- return null;
262
- }
263
- const values = node.arguments.map((arg) => {
264
- if (arg.type === 'ArgumentPlaceholder' ||
265
- arg.type === 'JSXNamespacedName' ||
266
- arg.type === 'SpreadElement') {
267
- return null;
268
- }
269
- return getNumericValue(arg);
270
- });
271
- if (values.some((value) => value === null)) {
272
- return null;
273
- }
274
- const [x1, y1, x2, y2] = values;
275
- return { type: 'bezier', x1, y1, x2, y2 };
276
- };
229
+ const getKeyframeEasing = (node) => (0, parse_keyframe_easing_expression_1.parseKeyframeEasingExpression)(node);
277
230
  const getKeyframeEasingArray = ({ easingNode, segmentCount, }) => {
278
231
  if (segmentCount === 0) {
279
232
  return [];
@@ -1,8 +1,10 @@
1
+ import type { GoogleFontSourceEdit } from '@remotion/studio-shared';
1
2
  import type { InteractivitySchema, SequenceNodePath } from 'remotion';
2
3
  export type SequencePropUpdate = {
3
4
  key: string;
4
5
  value: unknown;
5
6
  defaultValue: unknown | null;
7
+ googleFont?: GoogleFontSourceEdit | null;
6
8
  };
7
9
  export type RemovedProp = {
8
10
  key: string;