@remotion/studio-server 4.0.484 → 4.0.486
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.
- package/dist/codemods/duplicate-composition.js +8 -0
- package/dist/codemods/recast-mods.js +246 -5
- package/dist/codemods/split-jsx-sequence.d.ts +14 -0
- package/dist/codemods/split-jsx-sequence.js +345 -0
- package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +3 -1
- package/dist/codemods/update-sequence-props/update-sequence-props.js +406 -9
- package/dist/helpers/import-agnostic-node-path.js +30 -4
- package/dist/helpers/resolve-composition-component.d.ts +1 -0
- package/dist/helpers/resolve-composition-component.js +206 -9
- package/dist/preview-server/api-routes.js +2 -0
- package/dist/preview-server/routes/add-effect-keyframe.js +2 -2
- package/dist/preview-server/routes/add-effect.js +56 -53
- package/dist/preview-server/routes/add-keyframes.js +2 -2
- package/dist/preview-server/routes/add-sequence-keyframe.js +2 -2
- package/dist/preview-server/routes/apply-codemod.js +123 -101
- package/dist/preview-server/routes/apply-visual-control-change.js +83 -80
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +13 -1
- package/dist/preview-server/routes/can-update-sequence-props.js +101 -7
- package/dist/preview-server/routes/delete-effect.js +83 -80
- package/dist/preview-server/routes/delete-jsx-node.js +74 -71
- package/dist/preview-server/routes/delete-keyframes.js +2 -2
- package/dist/preview-server/routes/duplicate-effect.js +77 -74
- package/dist/preview-server/routes/duplicate-jsx-node.js +53 -50
- package/dist/preview-server/routes/insert-element.js +2 -2
- package/dist/preview-server/routes/insert-jsx-element.js +53 -4
- package/dist/preview-server/routes/move-keyframes.js +2 -2
- package/dist/preview-server/routes/paste-effects.js +59 -56
- package/dist/preview-server/routes/reorder-effect.js +55 -52
- package/dist/preview-server/routes/reorder-sequence.js +55 -52
- package/dist/preview-server/routes/save-effect-props.js +2 -2
- package/dist/preview-server/routes/save-sequence-props.d.ts +3 -1
- package/dist/preview-server/routes/save-sequence-props.js +208 -24
- package/dist/preview-server/routes/source-file-write-queue.d.ts +1 -0
- package/dist/preview-server/routes/source-file-write-queue.js +11 -0
- package/dist/preview-server/routes/split-jsx-sequence.d.ts +3 -0
- package/dist/preview-server/routes/split-jsx-sequence.js +66 -0
- package/dist/preview-server/routes/update-default-props.js +58 -55
- package/dist/preview-server/routes/update-effect-keyframe-settings.js +2 -2
- package/dist/preview-server/routes/update-sequence-keyframe-settings.js +2 -2
- package/dist/preview-server/undo-stack.d.ts +7 -1
- package/package.json +6 -6
|
@@ -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
|
});
|
|
@@ -96,6 +104,7 @@ const mapReturnStatement = (statement, transformation, changesMade, parentFolder
|
|
|
96
104
|
return statement;
|
|
97
105
|
}
|
|
98
106
|
if (transformation.type === 'new-composition' &&
|
|
107
|
+
transformation.folderName === null &&
|
|
99
108
|
(statement.argument.type === 'JSXElement' ||
|
|
100
109
|
statement.argument.type === 'JSXFragment')) {
|
|
101
110
|
return {
|
|
@@ -103,6 +112,15 @@ const mapReturnStatement = (statement, transformation, changesMade, parentFolder
|
|
|
103
112
|
argument: addNewCompositionToRootJsx(statement.argument, transformation, changesMade),
|
|
104
113
|
};
|
|
105
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
|
+
}
|
|
106
124
|
const replacement = transformLoneJsxElement(statement.argument, transformation, changesMade, parentFolderName);
|
|
107
125
|
if (replacement !== null) {
|
|
108
126
|
return { ...statement, argument: replacement };
|
|
@@ -176,6 +194,19 @@ const newCompositionElement = (transformation) => {
|
|
|
176
194
|
children: [],
|
|
177
195
|
};
|
|
178
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
|
+
};
|
|
179
210
|
const addNewCompositionToRootJsx = (root, transformation, changesMade) => {
|
|
180
211
|
if (changesMade.length > 0) {
|
|
181
212
|
return root;
|
|
@@ -191,6 +222,185 @@ const addNewCompositionToRootJsx = (root, transformation, changesMade) => {
|
|
|
191
222
|
}
|
|
192
223
|
return wrapInJsxFragment([root, newCompositionElement(transformation)]);
|
|
193
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
|
+
};
|
|
240
|
+
const addNewCompositionToFolder = (folderElement, transformation, changesMade) => {
|
|
241
|
+
var _a;
|
|
242
|
+
if (changesMade.length > 0) {
|
|
243
|
+
return folderElement;
|
|
244
|
+
}
|
|
245
|
+
changesMade.push({
|
|
246
|
+
description: 'Added new composition',
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
...folderElement,
|
|
250
|
+
openingElement: {
|
|
251
|
+
...folderElement.openingElement,
|
|
252
|
+
selfClosing: false,
|
|
253
|
+
},
|
|
254
|
+
closingElement: (_a = folderElement.closingElement) !== null && _a !== void 0 ? _a : {
|
|
255
|
+
type: 'JSXClosingElement',
|
|
256
|
+
name: folderElement.openingElement.name,
|
|
257
|
+
},
|
|
258
|
+
children: [
|
|
259
|
+
...folderElement.children,
|
|
260
|
+
newCompositionElement(transformation),
|
|
261
|
+
],
|
|
262
|
+
};
|
|
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
|
+
};
|
|
194
404
|
// When a <Composition> JSX element appears in a position where it cannot
|
|
195
405
|
// simply be removed from a parent's children list (e.g. as the sole return
|
|
196
406
|
// value of a wrapper component or as the concise body of an arrow function),
|
|
@@ -209,7 +419,13 @@ const transformLoneJsxElement = (expression, transformation, changesMade, parent
|
|
|
209
419
|
parentFolderName === transformation.parentName) ||
|
|
210
420
|
(transformation.type === 'rename-folder' &&
|
|
211
421
|
folderName === transformation.folderName &&
|
|
212
|
-
parentFolderName === transformation.parentName)
|
|
422
|
+
parentFolderName === transformation.parentName) ||
|
|
423
|
+
(transformation.type === 'new-composition' &&
|
|
424
|
+
folderName === transformation.folderName &&
|
|
425
|
+
parentFolderName === transformation.parentName) ||
|
|
426
|
+
(transformation.type === 'new-folder' &&
|
|
427
|
+
getChildFolderParentName({ folderName, parentFolderName }) ===
|
|
428
|
+
transformation.parentName));
|
|
213
429
|
if (!isFolderMatch) {
|
|
214
430
|
return null;
|
|
215
431
|
}
|
|
@@ -225,7 +441,14 @@ const transformLoneJsxElement = (expression, transformation, changesMade, parent
|
|
|
225
441
|
parentFolderName === transformation.parentName) ||
|
|
226
442
|
(transformation.type === 'rename-folder' &&
|
|
227
443
|
folderName === transformation.folderName &&
|
|
228
|
-
parentFolderName === transformation.parentName)
|
|
444
|
+
parentFolderName === transformation.parentName) ||
|
|
445
|
+
(transformation.type === 'new-composition' &&
|
|
446
|
+
folderName === transformation.folderName &&
|
|
447
|
+
parentFolderName === transformation.parentName) ||
|
|
448
|
+
(transformation.type === 'new-folder' &&
|
|
449
|
+
folderName !== null &&
|
|
450
|
+
getChildFolderParentName({ folderName, parentFolderName }) ===
|
|
451
|
+
transformation.parentName);
|
|
229
452
|
if (!isMatch) {
|
|
230
453
|
return null;
|
|
231
454
|
}
|
|
@@ -252,9 +475,6 @@ const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade, paren
|
|
|
252
475
|
.flat(1),
|
|
253
476
|
};
|
|
254
477
|
};
|
|
255
|
-
const getChildFolderParentName = ({ folderName, parentFolderName, }) => {
|
|
256
|
-
return [parentFolderName, folderName].filter(Boolean).join('/');
|
|
257
|
-
};
|
|
258
478
|
const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
|
|
259
479
|
const compId = getCompositionIdFromJSXElement(c);
|
|
260
480
|
const folderName = getFolderNameFromJSXElement(c);
|
|
@@ -318,6 +538,17 @@ const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
|
|
|
318
538
|
});
|
|
319
539
|
return c.children;
|
|
320
540
|
}
|
|
541
|
+
if (transformation.type === 'new-composition' &&
|
|
542
|
+
folderName === transformation.folderName &&
|
|
543
|
+
parentFolderName === transformation.parentName) {
|
|
544
|
+
return [addNewCompositionToFolder(c, transformation, changesMade)];
|
|
545
|
+
}
|
|
546
|
+
if (transformation.type === 'new-folder' &&
|
|
547
|
+
folderName !== null &&
|
|
548
|
+
getChildFolderParentName({ folderName, parentFolderName }) ===
|
|
549
|
+
transformation.parentName) {
|
|
550
|
+
return [addNewFolderToFolder(c, transformation, changesMade)];
|
|
551
|
+
}
|
|
321
552
|
const childParentFolderName = folderName
|
|
322
553
|
? getChildFolderParentName({ folderName, parentFolderName })
|
|
323
554
|
: parentFolderName;
|
|
@@ -330,6 +561,7 @@ const mapRecognizedType = (expression, transformation, changesMade, parentFolder
|
|
|
330
561
|
if (expression.type === 'ArrowFunctionExpression' ||
|
|
331
562
|
expression.type === 'FunctionExpression') {
|
|
332
563
|
if (transformation.type === 'new-composition' &&
|
|
564
|
+
transformation.folderName === null &&
|
|
333
565
|
(expression.body.type === 'JSXElement' ||
|
|
334
566
|
expression.body.type === 'JSXFragment')) {
|
|
335
567
|
return {
|
|
@@ -337,6 +569,15 @@ const mapRecognizedType = (expression, transformation, changesMade, parentFolder
|
|
|
337
569
|
body: addNewCompositionToRootJsx(expression.body, transformation, changesMade),
|
|
338
570
|
};
|
|
339
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
|
+
}
|
|
340
581
|
if (expression.type === 'ArrowFunctionExpression' &&
|
|
341
582
|
expression.body.type === 'JSXElement') {
|
|
342
583
|
const replacement = transformLoneJsxElement(expression.body, transformation, changesMade, parentFolderName);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SequenceNodePath } from 'remotion';
|
|
2
|
+
export declare const getSplitUnsupportedSequenceTagReason: (tagName: string) => string | null;
|
|
3
|
+
export declare const getIsSplittableSequenceTag: (tagName: string) => boolean;
|
|
4
|
+
export declare const splitJsxSequence: ({ input, nodePath, splitFrame, prettierConfigOverride, }: {
|
|
5
|
+
input: string;
|
|
6
|
+
nodePath: SequenceNodePath;
|
|
7
|
+
splitFrame: number;
|
|
8
|
+
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
output: string;
|
|
11
|
+
formatted: boolean;
|
|
12
|
+
nodeLabel: string;
|
|
13
|
+
logLine: number;
|
|
14
|
+
}>;
|