@remotion/studio-server 4.0.491 → 4.0.493
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/recast-mods.js +56 -48
- package/dist/codemods/split-jsx-sequence.js +5 -0
- package/dist/helpers/resolve-composition-component.js +30 -6
- package/dist/preview-server/routes/apply-codemod.js +11 -0
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +6 -3
- package/dist/preview-server/routes/can-update-sequence-props.js +19 -11
- package/dist/preview-server/routes/save-sequence-props.js +1 -0
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +2 -1
- package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +2 -1
- package/dist/preview-server/sequence-props-watchers.d.ts +4 -2
- package/dist/preview-server/sequence-props-watchers.js +11 -6
- package/dist/preview-server/undo-stack.d.ts +3 -1
- package/dist/routes.js +1 -0
- package/package.json +6 -6
|
@@ -434,6 +434,8 @@ const transformLoneJsxElement = (expression, transformation, changesMade, parent
|
|
|
434
434
|
compId === transformation.idToDelete) ||
|
|
435
435
|
(transformation.type === 'rename-composition' &&
|
|
436
436
|
compId === transformation.idToRename) ||
|
|
437
|
+
(transformation.type === 'update-composition-metadata' &&
|
|
438
|
+
compId === transformation.idToUpdate) ||
|
|
437
439
|
(transformation.type === 'duplicate-composition' &&
|
|
438
440
|
compId === transformation.idToDuplicate) ||
|
|
439
441
|
(transformation.type === 'delete-folder' &&
|
|
@@ -512,6 +514,21 @@ const mapJsxChild = (c, transformation, changesMade, parentFolderName) => {
|
|
|
512
514
|
}),
|
|
513
515
|
];
|
|
514
516
|
}
|
|
517
|
+
if (transformation.type === 'update-composition-metadata' &&
|
|
518
|
+
compId === transformation.idToUpdate) {
|
|
519
|
+
return [
|
|
520
|
+
changeComposition({
|
|
521
|
+
jsxElement: c,
|
|
522
|
+
newCompositionId: null,
|
|
523
|
+
newCompositionFps: transformation.newFps,
|
|
524
|
+
newCompositionDurationInFrames: transformation.newDurationInFrames,
|
|
525
|
+
newCompositionHeight: transformation.newHeight,
|
|
526
|
+
newCompositionWidth: transformation.newWidth,
|
|
527
|
+
changesMade,
|
|
528
|
+
newTagToUse: null,
|
|
529
|
+
}),
|
|
530
|
+
];
|
|
531
|
+
}
|
|
515
532
|
if (transformation.type === 'delete-composition' &&
|
|
516
533
|
compId === transformation.idToDelete) {
|
|
517
534
|
changesMade.push({
|
|
@@ -783,7 +800,8 @@ const changeComposition = ({ jsxElement, newCompositionId, newCompositionFps, ne
|
|
|
783
800
|
// id="one"
|
|
784
801
|
if (attribute.name.name === 'id' &&
|
|
785
802
|
attribute.value &&
|
|
786
|
-
attribute.value.type === 'StringLiteral'
|
|
803
|
+
attribute.value.type === 'StringLiteral' &&
|
|
804
|
+
newCompositionId !== null) {
|
|
787
805
|
changesMade.push({
|
|
788
806
|
description: 'Replaced composition id',
|
|
789
807
|
});
|
|
@@ -796,7 +814,8 @@ const changeComposition = ({ jsxElement, newCompositionId, newCompositionFps, ne
|
|
|
796
814
|
if (attribute.name.name === 'id' &&
|
|
797
815
|
attribute.value &&
|
|
798
816
|
attribute.value.type === 'JSXExpressionContainer' &&
|
|
799
|
-
attribute.value.expression.type === 'StringLiteral'
|
|
817
|
+
attribute.value.expression.type === 'StringLiteral' &&
|
|
818
|
+
newCompositionId !== null) {
|
|
800
819
|
changesMade.push({
|
|
801
820
|
description: 'Replaced composition id',
|
|
802
821
|
});
|
|
@@ -811,85 +830,74 @@ const changeComposition = ({ jsxElement, newCompositionId, newCompositionFps, ne
|
|
|
811
830
|
},
|
|
812
831
|
};
|
|
813
832
|
}
|
|
814
|
-
if (attribute.name.name === 'fps' &&
|
|
815
|
-
attribute.value &&
|
|
816
|
-
attribute.value.type === 'JSXExpressionContainer' &&
|
|
817
|
-
attribute.value.expression.type === 'NumericLiteral' &&
|
|
818
|
-
newCompositionFps !== null) {
|
|
833
|
+
if (attribute.name.name === 'fps' && newCompositionFps !== null) {
|
|
819
834
|
changesMade.push({
|
|
820
835
|
description: 'Replaced FPS',
|
|
821
836
|
});
|
|
822
837
|
return {
|
|
823
838
|
...attribute,
|
|
824
|
-
value:
|
|
825
|
-
...attribute.value,
|
|
826
|
-
expression: {
|
|
827
|
-
...attribute.value.expression,
|
|
828
|
-
value: newCompositionFps,
|
|
829
|
-
},
|
|
830
|
-
},
|
|
839
|
+
value: b.jsxExpressionContainer(b.numericLiteral(newCompositionFps)),
|
|
831
840
|
};
|
|
832
841
|
}
|
|
833
842
|
if (attribute.name.name === 'durationInFrames' &&
|
|
834
|
-
attribute.value &&
|
|
835
|
-
attribute.value.type === 'JSXExpressionContainer' &&
|
|
836
|
-
attribute.value.expression.type === 'NumericLiteral' &&
|
|
837
843
|
newCompositionDurationInFrames !== null) {
|
|
838
844
|
changesMade.push({
|
|
839
845
|
description: 'Replaced durationInFrames',
|
|
840
846
|
});
|
|
841
847
|
return {
|
|
842
848
|
...attribute,
|
|
843
|
-
value:
|
|
844
|
-
...attribute.value,
|
|
845
|
-
expression: {
|
|
846
|
-
...attribute.value.expression,
|
|
847
|
-
value: newCompositionDurationInFrames,
|
|
848
|
-
},
|
|
849
|
-
},
|
|
849
|
+
value: b.jsxExpressionContainer(b.numericLiteral(newCompositionDurationInFrames)),
|
|
850
850
|
};
|
|
851
851
|
}
|
|
852
|
-
if (attribute.name.name === 'width' &&
|
|
853
|
-
attribute.value &&
|
|
854
|
-
attribute.value.type === 'JSXExpressionContainer' &&
|
|
855
|
-
attribute.value.expression.type === 'NumericLiteral' &&
|
|
856
|
-
newCompositionWidth !== null) {
|
|
852
|
+
if (attribute.name.name === 'width' && newCompositionWidth !== null) {
|
|
857
853
|
changesMade.push({
|
|
858
854
|
description: 'Replaced width',
|
|
859
855
|
});
|
|
860
856
|
return {
|
|
861
857
|
...attribute,
|
|
862
|
-
value:
|
|
863
|
-
...attribute.value,
|
|
864
|
-
expression: {
|
|
865
|
-
...attribute.value.expression,
|
|
866
|
-
value: newCompositionWidth,
|
|
867
|
-
},
|
|
868
|
-
},
|
|
858
|
+
value: b.jsxExpressionContainer(b.numericLiteral(newCompositionWidth)),
|
|
869
859
|
};
|
|
870
860
|
}
|
|
871
|
-
if (attribute.name.name === 'height' &&
|
|
872
|
-
attribute.value &&
|
|
873
|
-
attribute.value.type === 'JSXExpressionContainer' &&
|
|
874
|
-
attribute.value.expression.type === 'NumericLiteral' &&
|
|
875
|
-
newCompositionHeight !== null) {
|
|
861
|
+
if (attribute.name.name === 'height' && newCompositionHeight !== null) {
|
|
876
862
|
changesMade.push({
|
|
877
863
|
description: 'Replaced height',
|
|
878
864
|
});
|
|
879
865
|
return {
|
|
880
866
|
...attribute,
|
|
881
|
-
value:
|
|
882
|
-
...attribute.value,
|
|
883
|
-
expression: {
|
|
884
|
-
...attribute.value.expression,
|
|
885
|
-
value: newCompositionHeight,
|
|
886
|
-
},
|
|
887
|
-
},
|
|
867
|
+
value: b.jsxExpressionContainer(b.numericLiteral(newCompositionHeight)),
|
|
888
868
|
};
|
|
889
869
|
}
|
|
890
870
|
return attribute;
|
|
891
871
|
})
|
|
892
872
|
.filter(Boolean);
|
|
873
|
+
if (newCompositionFps !== null &&
|
|
874
|
+
!attributes.some((attribute) => attribute.type === 'JSXAttribute' &&
|
|
875
|
+
attribute.name.type === 'JSXIdentifier' &&
|
|
876
|
+
attribute.name.name === 'fps')) {
|
|
877
|
+
changesMade.push({ description: 'Added FPS' });
|
|
878
|
+
attributes.push(jsxAttributeWithExpression('fps', b.numericLiteral(newCompositionFps)));
|
|
879
|
+
}
|
|
880
|
+
if (newCompositionDurationInFrames !== null &&
|
|
881
|
+
!attributes.some((attribute) => attribute.type === 'JSXAttribute' &&
|
|
882
|
+
attribute.name.type === 'JSXIdentifier' &&
|
|
883
|
+
attribute.name.name === 'durationInFrames')) {
|
|
884
|
+
changesMade.push({ description: 'Added durationInFrames' });
|
|
885
|
+
attributes.push(jsxAttributeWithExpression('durationInFrames', b.numericLiteral(newCompositionDurationInFrames)));
|
|
886
|
+
}
|
|
887
|
+
if (newCompositionWidth !== null &&
|
|
888
|
+
!attributes.some((attribute) => attribute.type === 'JSXAttribute' &&
|
|
889
|
+
attribute.name.type === 'JSXIdentifier' &&
|
|
890
|
+
attribute.name.name === 'width')) {
|
|
891
|
+
changesMade.push({ description: 'Added width' });
|
|
892
|
+
attributes.push(jsxAttributeWithExpression('width', b.numericLiteral(newCompositionWidth)));
|
|
893
|
+
}
|
|
894
|
+
if (newCompositionHeight !== null &&
|
|
895
|
+
!attributes.some((attribute) => attribute.type === 'JSXAttribute' &&
|
|
896
|
+
attribute.name.type === 'JSXIdentifier' &&
|
|
897
|
+
attribute.name.name === 'height')) {
|
|
898
|
+
changesMade.push({ description: 'Added height' });
|
|
899
|
+
attributes.push(jsxAttributeWithExpression('height', b.numericLiteral(newCompositionHeight)));
|
|
900
|
+
}
|
|
893
901
|
const newName = newTagToUse !== null && newTagToUse !== void 0 ? newTagToUse : name.name;
|
|
894
902
|
if (newName !== name.name) {
|
|
895
903
|
changesMade.push({
|
|
@@ -74,6 +74,11 @@ const getStaticNumber = (attribute) => {
|
|
|
74
74
|
if (expression.type === 'NumericLiteral') {
|
|
75
75
|
return expression.value;
|
|
76
76
|
}
|
|
77
|
+
if (expression.type === 'UnaryExpression' &&
|
|
78
|
+
expression.operator === '-' &&
|
|
79
|
+
expression.argument.type === 'NumericLiteral') {
|
|
80
|
+
return -expression.argument.value;
|
|
81
|
+
}
|
|
77
82
|
if (expression.type === 'Identifier' && expression.name === 'Infinity') {
|
|
78
83
|
return Infinity;
|
|
79
84
|
}
|
|
@@ -508,6 +508,9 @@ const getComponentRootNode = (declaration) => {
|
|
|
508
508
|
const createSequenceElement = () => {
|
|
509
509
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier('Sequence'), []), recast.types.builders.jsxClosingElement(recast.types.builders.jsxIdentifier('Sequence')), []);
|
|
510
510
|
};
|
|
511
|
+
const createSequenceWithChild = ({ child, sequenceLocalName, }) => {
|
|
512
|
+
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(sequenceLocalName), []), recast.types.builders.jsxClosingElement(recast.types.builders.jsxIdentifier(sequenceLocalName)), [child]);
|
|
513
|
+
};
|
|
511
514
|
const createNumberAttribute = (name, value) => {
|
|
512
515
|
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.numericLiteral(value)));
|
|
513
516
|
};
|
|
@@ -1019,8 +1022,8 @@ const createCompositionComponentElement = ({ localName, props, }) => {
|
|
|
1019
1022
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), attributes, true), null, []);
|
|
1020
1023
|
};
|
|
1021
1024
|
const addElementToComponentRoot = ({ ast, exportName, element, }) => {
|
|
1022
|
-
var _a;
|
|
1023
|
-
var
|
|
1025
|
+
var _a, _b;
|
|
1026
|
+
var _c, _d;
|
|
1024
1027
|
const declaration = getDeclarationByExportName({ ast, exportName });
|
|
1025
1028
|
if (!declaration) {
|
|
1026
1029
|
throw new Error('Could not find composition component declaration');
|
|
@@ -1033,9 +1036,6 @@ const addElementToComponentRoot = ({ ast, exportName, element, }) => {
|
|
|
1033
1036
|
}
|
|
1034
1037
|
throw new Error('Composition component does not return JSX');
|
|
1035
1038
|
}
|
|
1036
|
-
if (rootNode.type === 'JSXElement' && rootNode.openingElement.selfClosing) {
|
|
1037
|
-
throw new Error('Cannot insert into a self-closing root JSX element');
|
|
1038
|
-
}
|
|
1039
1039
|
const CANVAS_ROOT_ELEMENTS = [
|
|
1040
1040
|
'ThreeCanvas',
|
|
1041
1041
|
'RiveCanvas',
|
|
@@ -1047,11 +1047,35 @@ const addElementToComponentRoot = ({ ast, exportName, element, }) => {
|
|
|
1047
1047
|
CANVAS_ROOT_ELEMENTS.includes(rootNode.openingElement.name.name)) {
|
|
1048
1048
|
throw new Error(`Cannot insert a JSX element into a composition whose root element is <${rootNode.openingElement.name.name}>`);
|
|
1049
1049
|
}
|
|
1050
|
+
if (rootNode.type === 'JSXElement' && rootNode.openingElement.selfClosing) {
|
|
1051
|
+
const fragment = recast.types.builders.jsxFragment(recast.types.builders.jsxOpeningFragment(), recast.types.builders.jsxClosingFragment(), [
|
|
1052
|
+
createSequenceWithChild({
|
|
1053
|
+
child: rootNode,
|
|
1054
|
+
sequenceLocalName: ensureSequenceImport(ast),
|
|
1055
|
+
}),
|
|
1056
|
+
element,
|
|
1057
|
+
]);
|
|
1058
|
+
let replaced = false;
|
|
1059
|
+
recast.types.visit(ast, {
|
|
1060
|
+
visitJSXElement(astPath) {
|
|
1061
|
+
if (astPath.node === rootNode) {
|
|
1062
|
+
astPath.replace(fragment);
|
|
1063
|
+
replaced = true;
|
|
1064
|
+
return false;
|
|
1065
|
+
}
|
|
1066
|
+
this.traverse(astPath);
|
|
1067
|
+
},
|
|
1068
|
+
});
|
|
1069
|
+
if (!replaced) {
|
|
1070
|
+
throw new Error('Could not replace composition component root');
|
|
1071
|
+
}
|
|
1072
|
+
return (_c = (_a = rootNode.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _c !== void 0 ? _c : 1;
|
|
1073
|
+
}
|
|
1050
1074
|
if (!rootNode.children) {
|
|
1051
1075
|
throw new Error('Composition component root does not accept children');
|
|
1052
1076
|
}
|
|
1053
1077
|
rootNode.children.push(element);
|
|
1054
|
-
return (
|
|
1078
|
+
return (_d = (_b = rootNode.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _d !== void 0 ? _d : 1;
|
|
1055
1079
|
};
|
|
1056
1080
|
const getDefaultExportDeclaration = (ast) => {
|
|
1057
1081
|
let declaration = null;
|
|
@@ -40,6 +40,9 @@ const getCodemodLogMessage = (codemod) => {
|
|
|
40
40
|
if (codemod.type === 'rename-composition') {
|
|
41
41
|
return `Renamed composition "${codemod.idToRename}" to "${codemod.newId}"`;
|
|
42
42
|
}
|
|
43
|
+
if (codemod.type === 'update-composition-metadata') {
|
|
44
|
+
return `Updated metadata of composition "${codemod.idToUpdate}"`;
|
|
45
|
+
}
|
|
43
46
|
if (codemod.type === 'delete-composition') {
|
|
44
47
|
return `Deleted composition "${codemod.idToDelete}"`;
|
|
45
48
|
}
|
|
@@ -84,6 +87,14 @@ const getCodemodUndoDescription = (codemod) => {
|
|
|
84
87
|
entryType: codemod.type,
|
|
85
88
|
};
|
|
86
89
|
}
|
|
90
|
+
if (codemod.type === 'update-composition-metadata') {
|
|
91
|
+
const label = `metadata of composition "${codemod.idToUpdate}"`;
|
|
92
|
+
return {
|
|
93
|
+
undoMessage: `↩️ Update of ${label}`,
|
|
94
|
+
redoMessage: `↪️ Update of ${label}`,
|
|
95
|
+
entryType: codemod.type,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
87
98
|
if (codemod.type === 'duplicate-composition') {
|
|
88
99
|
const label = `composition "${codemod.idToDuplicate}" to "${codemod.newId}"`;
|
|
89
100
|
return {
|
|
@@ -23,28 +23,31 @@ export declare const hasJsxChildrenAttribute: (jsxElement: JSXOpeningElement) =>
|
|
|
23
23
|
export declare const getStaticJsxTextContent: (jsxElement: JSXElement) => StaticJsxTextContent | null;
|
|
24
24
|
export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
|
|
25
25
|
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
26
|
-
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, componentIdentity, keys, effects, videoConfigValues, }: {
|
|
26
|
+
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, componentIdentity, keys, assetKeys, effects, videoConfigValues, }: {
|
|
27
27
|
fileContents: string;
|
|
28
28
|
nodePath: SequenceNodePath;
|
|
29
29
|
componentIdentity: string | null;
|
|
30
30
|
keys: string[];
|
|
31
|
+
assetKeys?: string[] | undefined;
|
|
31
32
|
effects: string[][];
|
|
32
33
|
videoConfigValues: VideoConfigValues | null;
|
|
33
34
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
34
|
-
export declare const computeSequencePropsStatus: ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, videoConfigValues, }: {
|
|
35
|
+
export declare const computeSequencePropsStatus: ({ fileName, nodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, videoConfigValues, }: {
|
|
35
36
|
fileName: string;
|
|
36
37
|
nodePath: SequenceNodePath;
|
|
37
38
|
componentIdentity: string | null;
|
|
38
39
|
keys: string[];
|
|
40
|
+
assetKeys?: string[] | undefined;
|
|
39
41
|
effects: string[][];
|
|
40
42
|
remotionRoot: string;
|
|
41
43
|
videoConfigValues: VideoConfigValues | null;
|
|
42
44
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
43
|
-
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, videoConfigValues, }: {
|
|
45
|
+
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, videoConfigValues, }: {
|
|
44
46
|
fileName: string;
|
|
45
47
|
line: number;
|
|
46
48
|
componentIdentity: string | null;
|
|
47
49
|
keys: string[];
|
|
50
|
+
assetKeys?: string[] | undefined;
|
|
48
51
|
effects: string[][];
|
|
49
52
|
remotionRoot: string;
|
|
50
53
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
@@ -480,7 +480,7 @@ const getComputedStatus = (node, ast, videoConfigValues) => {
|
|
|
480
480
|
};
|
|
481
481
|
};
|
|
482
482
|
exports.getComputedStatus = getComputedStatus;
|
|
483
|
-
const getPropsStatus = (jsxElement, ast, videoConfigValues) => {
|
|
483
|
+
const getPropsStatus = (jsxElement, ast, videoConfigValues, assetKeys) => {
|
|
484
484
|
const props = {};
|
|
485
485
|
for (const attr of jsxElement.attributes) {
|
|
486
486
|
if (attr.type === 'JSXSpreadAttribute') {
|
|
@@ -504,11 +504,14 @@ const getPropsStatus = (jsxElement, ast, videoConfigValues) => {
|
|
|
504
504
|
}
|
|
505
505
|
if (value.type === 'JSXExpressionContainer') {
|
|
506
506
|
const { expression } = value;
|
|
507
|
+
const staticValueOptions = {
|
|
508
|
+
allowSpecialValues: assetKeys.includes(name),
|
|
509
|
+
};
|
|
507
510
|
if (expression.type === 'JSXEmptyExpression') {
|
|
508
511
|
props[name] = computedStatus();
|
|
509
512
|
continue;
|
|
510
513
|
}
|
|
511
|
-
if (!(0, exports.isStaticValue)(expression)) {
|
|
514
|
+
if (!(0, exports.isStaticValue)(expression, staticValueOptions)) {
|
|
512
515
|
const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
|
|
513
516
|
node: expression,
|
|
514
517
|
videoConfigValues,
|
|
@@ -518,7 +521,7 @@ const getPropsStatus = (jsxElement, ast, videoConfigValues) => {
|
|
|
518
521
|
: (0, exports.getComputedStatus)(expression, ast, videoConfigValues);
|
|
519
522
|
continue;
|
|
520
523
|
}
|
|
521
|
-
props[name] = staticStatus((0, exports.extractStaticValue)(expression), null);
|
|
524
|
+
props[name] = staticStatus((0, exports.extractStaticValue)(expression, staticValueOptions), null);
|
|
522
525
|
continue;
|
|
523
526
|
}
|
|
524
527
|
props[name] = computedStatus();
|
|
@@ -666,7 +669,7 @@ const validateStyleValue = (childKey, value) => {
|
|
|
666
669
|
}
|
|
667
670
|
return true;
|
|
668
671
|
};
|
|
669
|
-
const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfigValues, }) => {
|
|
672
|
+
const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfigValues, allowSpecialValues, }) => {
|
|
670
673
|
const attr = jsxElement.attributes.find((a) => a.type !== 'JSXSpreadAttribute' &&
|
|
671
674
|
a.name.type !== 'JSXNamespacedName' &&
|
|
672
675
|
a.name.name === parentKey);
|
|
@@ -692,7 +695,8 @@ const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfig
|
|
|
692
695
|
return staticStatus(undefined, null);
|
|
693
696
|
}
|
|
694
697
|
const propValue = prop.value;
|
|
695
|
-
|
|
698
|
+
const staticValueOptions = { allowSpecialValues };
|
|
699
|
+
if (!(0, exports.isStaticValue)(propValue, staticValueOptions)) {
|
|
696
700
|
const numericExpression = (0, video_config_numeric_expression_1.parseVideoConfigNumericExpression)({
|
|
697
701
|
node: propValue,
|
|
698
702
|
videoConfigValues,
|
|
@@ -701,7 +705,7 @@ const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfig
|
|
|
701
705
|
? staticStatus(numericExpression.value, numericExpression)
|
|
702
706
|
: (0, exports.getComputedStatus)(propValue, ast, videoConfigValues);
|
|
703
707
|
}
|
|
704
|
-
const propStatus = (0, exports.extractStaticValue)(propValue);
|
|
708
|
+
const propStatus = (0, exports.extractStaticValue)(propValue, staticValueOptions);
|
|
705
709
|
if (!validateStyleValue(childKey, propStatus)) {
|
|
706
710
|
return computedStatus();
|
|
707
711
|
}
|
|
@@ -716,8 +720,8 @@ const computeEffectsForJsx = ({ ast, jsxElement, effects, videoConfigValues, })
|
|
|
716
720
|
videoConfigValues,
|
|
717
721
|
}));
|
|
718
722
|
};
|
|
719
|
-
const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys, videoConfigValues, }) => {
|
|
720
|
-
const allProps = getPropsStatus(jsxElement, ast, videoConfigValues);
|
|
723
|
+
const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys, assetKeys, videoConfigValues, }) => {
|
|
724
|
+
const allProps = getPropsStatus(jsxElement, ast, videoConfigValues, assetKeys);
|
|
721
725
|
const filteredProps = {};
|
|
722
726
|
for (const key of keys) {
|
|
723
727
|
if (key === 'children') {
|
|
@@ -744,6 +748,7 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys,
|
|
|
744
748
|
parentKey: key.slice(0, dotIndex),
|
|
745
749
|
childKey: key.slice(dotIndex + 1),
|
|
746
750
|
videoConfigValues,
|
|
751
|
+
allowSpecialValues: assetKeys.includes(key),
|
|
747
752
|
});
|
|
748
753
|
}
|
|
749
754
|
else if (key in allProps) {
|
|
@@ -755,7 +760,7 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys,
|
|
|
755
760
|
}
|
|
756
761
|
return filteredProps;
|
|
757
762
|
};
|
|
758
|
-
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, effects, videoConfigValues, }) => {
|
|
763
|
+
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
|
|
759
764
|
var _a;
|
|
760
765
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
761
766
|
const videoConfigIdentifierValues = (0, video_config_values_1.getVideoConfigIdentifierValues)({
|
|
@@ -778,6 +783,7 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, compone
|
|
|
778
783
|
jsxElementNode,
|
|
779
784
|
ast,
|
|
780
785
|
keys,
|
|
786
|
+
assetKeys,
|
|
781
787
|
videoConfigValues: videoConfigIdentifierValues,
|
|
782
788
|
});
|
|
783
789
|
const effectsStatuses = computeEffectsForJsx({
|
|
@@ -793,7 +799,7 @@ const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, compone
|
|
|
793
799
|
};
|
|
794
800
|
};
|
|
795
801
|
exports.computeSequencePropsStatusFromContent = computeSequencePropsStatusFromContent;
|
|
796
|
-
const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, effects, remotionRoot, videoConfigValues, }) => {
|
|
802
|
+
const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, keys, assetKeys = [], effects, remotionRoot, videoConfigValues, }) => {
|
|
797
803
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
798
804
|
remotionRoot,
|
|
799
805
|
fileName,
|
|
@@ -805,12 +811,13 @@ const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, key
|
|
|
805
811
|
nodePath,
|
|
806
812
|
componentIdentity,
|
|
807
813
|
keys,
|
|
814
|
+
assetKeys,
|
|
808
815
|
effects,
|
|
809
816
|
videoConfigValues,
|
|
810
817
|
});
|
|
811
818
|
};
|
|
812
819
|
exports.computeSequencePropsStatus = computeSequencePropsStatus;
|
|
813
|
-
const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, effects, remotionRoot, logLevel, videoConfigValues, }) => {
|
|
820
|
+
const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, assetKeys = [], effects, remotionRoot, logLevel, videoConfigValues, }) => {
|
|
814
821
|
try {
|
|
815
822
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
816
823
|
remotionRoot,
|
|
@@ -835,6 +842,7 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
|
|
|
835
842
|
nodePath: resolvedNodePath,
|
|
836
843
|
componentIdentity,
|
|
837
844
|
keys,
|
|
845
|
+
assetKeys,
|
|
838
846
|
effects,
|
|
839
847
|
remotionRoot,
|
|
840
848
|
videoConfigValues,
|
|
@@ -331,6 +331,7 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
331
331
|
const newStatus = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
|
|
332
332
|
fileContents: output,
|
|
333
333
|
keys: (0, studio_shared_1.getAllSchemaKeys)(edit.schema),
|
|
334
|
+
assetKeys: (0, studio_shared_1.getAssetSchemaKeys)(edit.schema),
|
|
334
335
|
nodePath: edit.nodePath.nodePath,
|
|
335
336
|
componentIdentity: null,
|
|
336
337
|
effects: [],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.subscribeToSequenceProps = void 0;
|
|
4
4
|
const sequence_props_watchers_1 = require("../sequence-props-watchers");
|
|
5
|
-
const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, componentIdentity, keys, effects, clientId, videoConfigValues, }, remotionRoot, logLevel, }) => {
|
|
5
|
+
const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, componentIdentity, keys, assetKeys = [], effects, clientId, videoConfigValues, }, remotionRoot, logLevel, }) => {
|
|
6
6
|
const result = (0, sequence_props_watchers_1.subscribeToSequencePropsWatchers)({
|
|
7
7
|
fileName,
|
|
8
8
|
line,
|
|
@@ -10,6 +10,7 @@ const subscribeToSequenceProps = ({ input: { fileName, line, column, nodePath, c
|
|
|
10
10
|
nodePath,
|
|
11
11
|
componentIdentity,
|
|
12
12
|
keys,
|
|
13
|
+
assetKeys,
|
|
13
14
|
effects,
|
|
14
15
|
remotionRoot,
|
|
15
16
|
clientId,
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.unsubscribeFromSequenceProps = void 0;
|
|
4
4
|
const sequence_props_watchers_1 = require("../sequence-props-watchers");
|
|
5
|
-
const unsubscribeFromSequenceProps = ({ input: { fileName, nodePath, clientId, sequenceKeys, effectKeys }, remotionRoot, }) => {
|
|
5
|
+
const unsubscribeFromSequenceProps = ({ input: { fileName, nodePath, clientId, sequenceKeys, assetKeys = [], effectKeys, }, remotionRoot, }) => {
|
|
6
6
|
(0, sequence_props_watchers_1.unsubscribeFromSequencePropsWatchers)({
|
|
7
7
|
fileName,
|
|
8
8
|
nodePath: nodePath.nodePath,
|
|
9
9
|
remotionRoot,
|
|
10
10
|
clientId,
|
|
11
11
|
sequenceKeys,
|
|
12
|
+
assetKeys,
|
|
12
13
|
effectKeys,
|
|
13
14
|
videoConfigValues: nodePath.videoConfigValues,
|
|
14
15
|
});
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import { type SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
|
|
2
2
|
import type { SequenceNodePath, VideoConfigValues } from 'remotion';
|
|
3
|
-
export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }: {
|
|
3
|
+
export declare const subscribeToSequencePropsWatchers: ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }: {
|
|
4
4
|
fileName: string;
|
|
5
5
|
line: number;
|
|
6
6
|
column: number;
|
|
7
7
|
nodePath: SequenceNodePath | null;
|
|
8
8
|
componentIdentity: string | null;
|
|
9
9
|
keys: string[];
|
|
10
|
+
assetKeys: string[];
|
|
10
11
|
effects: string[][];
|
|
11
12
|
remotionRoot: string;
|
|
12
13
|
clientId: string;
|
|
13
14
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
14
15
|
videoConfigValues: VideoConfigValues;
|
|
15
16
|
}) => SubscribeToSequencePropsResponse;
|
|
16
|
-
export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, videoConfigValues, }: {
|
|
17
|
+
export declare const unsubscribeFromSequencePropsWatchers: ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, assetKeys, effectKeys, videoConfigValues, }: {
|
|
17
18
|
fileName: string;
|
|
18
19
|
nodePath: SequenceNodePath;
|
|
19
20
|
remotionRoot: string;
|
|
20
21
|
clientId: string;
|
|
21
22
|
sequenceKeys: string[];
|
|
23
|
+
assetKeys: string[];
|
|
22
24
|
effectKeys: string[][];
|
|
23
25
|
videoConfigValues: VideoConfigValues | null;
|
|
24
26
|
}) => void;
|
|
@@ -14,8 +14,8 @@ const live_events_1 = require("./live-events");
|
|
|
14
14
|
const node_path_cache_1 = require("./node-path-cache");
|
|
15
15
|
const can_update_sequence_props_1 = require("./routes/can-update-sequence-props");
|
|
16
16
|
const sequencePropsWatchers = {};
|
|
17
|
-
const getWatcherKey = (nodePath) => `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath)}:${JSON.stringify(nodePath.videoConfigValues)}`;
|
|
18
|
-
const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, componentIdentity, keys, effects, remotionRoot, logLevel, videoConfigValues, }) => {
|
|
17
|
+
const getWatcherKey = (nodePath, assetKeys) => `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath)}:${assetKeys.join('\0')}:${JSON.stringify(nodePath.videoConfigValues)}`;
|
|
18
|
+
const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, videoConfigValues, }) => {
|
|
19
19
|
if (preferredNodePath) {
|
|
20
20
|
try {
|
|
21
21
|
const fromNodePath = (0, can_update_sequence_props_1.computeSequencePropsStatus)({
|
|
@@ -23,6 +23,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
|
|
|
23
23
|
nodePath: preferredNodePath,
|
|
24
24
|
componentIdentity,
|
|
25
25
|
keys,
|
|
26
|
+
assetKeys,
|
|
26
27
|
effects,
|
|
27
28
|
remotionRoot,
|
|
28
29
|
videoConfigValues,
|
|
@@ -56,6 +57,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
|
|
|
56
57
|
nodePath: cachedNodePath,
|
|
57
58
|
componentIdentity,
|
|
58
59
|
keys,
|
|
60
|
+
assetKeys,
|
|
59
61
|
effects,
|
|
60
62
|
remotionRoot,
|
|
61
63
|
videoConfigValues,
|
|
@@ -88,6 +90,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
|
|
|
88
90
|
line,
|
|
89
91
|
componentIdentity,
|
|
90
92
|
keys,
|
|
93
|
+
assetKeys,
|
|
91
94
|
effects,
|
|
92
95
|
remotionRoot,
|
|
93
96
|
logLevel,
|
|
@@ -95,7 +98,7 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
|
|
|
95
98
|
});
|
|
96
99
|
return status;
|
|
97
100
|
};
|
|
98
|
-
const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }) => {
|
|
101
|
+
const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: preferredNodePath, componentIdentity, keys, assetKeys, effects, remotionRoot, clientId, logLevel, videoConfigValues, }) => {
|
|
99
102
|
var _a;
|
|
100
103
|
const initialResult = getSequencePropsStatus({
|
|
101
104
|
fileName,
|
|
@@ -104,6 +107,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
104
107
|
preferredNodePath,
|
|
105
108
|
componentIdentity,
|
|
106
109
|
keys,
|
|
110
|
+
assetKeys,
|
|
107
111
|
effects,
|
|
108
112
|
remotionRoot,
|
|
109
113
|
logLevel,
|
|
@@ -116,7 +120,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
116
120
|
// Cache the resolved nodePath for future lookups with stale source maps
|
|
117
121
|
(0, node_path_cache_1.setCachedNodePath)(fileName, line, column, initialResult.nodePath.nodePath);
|
|
118
122
|
const { nodePath } = initialResult;
|
|
119
|
-
const watcherKey = getWatcherKey(nodePath);
|
|
123
|
+
const watcherKey = getWatcherKey(nodePath, assetKeys);
|
|
120
124
|
// If a watcher already exists for this key, just bump the ref count
|
|
121
125
|
if ((_a = sequencePropsWatchers[clientId]) === null || _a === void 0 ? void 0 : _a[watcherKey]) {
|
|
122
126
|
sequencePropsWatchers[clientId][watcherKey].refCount++;
|
|
@@ -138,6 +142,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
138
142
|
nodePath: nodePath.nodePath,
|
|
139
143
|
componentIdentity,
|
|
140
144
|
keys,
|
|
145
|
+
assetKeys,
|
|
141
146
|
effects,
|
|
142
147
|
videoConfigValues,
|
|
143
148
|
});
|
|
@@ -181,7 +186,7 @@ const subscribeToSequencePropsWatchers = ({ fileName, line, column, nodePath: pr
|
|
|
181
186
|
return initialResult;
|
|
182
187
|
};
|
|
183
188
|
exports.subscribeToSequencePropsWatchers = subscribeToSequencePropsWatchers;
|
|
184
|
-
const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, effectKeys, videoConfigValues, }) => {
|
|
189
|
+
const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot, clientId, sequenceKeys, assetKeys, effectKeys, videoConfigValues, }) => {
|
|
185
190
|
const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
|
|
186
191
|
const watcherKey = getWatcherKey({
|
|
187
192
|
absolutePath,
|
|
@@ -189,7 +194,7 @@ const unsubscribeFromSequencePropsWatchers = ({ fileName, nodePath, remotionRoot
|
|
|
189
194
|
sequenceKeys,
|
|
190
195
|
effectKeys,
|
|
191
196
|
videoConfigValues,
|
|
192
|
-
});
|
|
197
|
+
}, assetKeys);
|
|
193
198
|
if (!sequencePropsWatchers[clientId] ||
|
|
194
199
|
!sequencePropsWatchers[clientId][watcherKey]) {
|
|
195
200
|
return;
|
|
@@ -3,7 +3,7 @@ export interface UndoEntryDescription {
|
|
|
3
3
|
undoMessage: string;
|
|
4
4
|
redoMessage: string;
|
|
5
5
|
}
|
|
6
|
-
type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-node' | 'duplicate-jsx-node' | 'split-jsx-sequence' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'new-composition' | 'duplicate-composition' | 'move-composition-to-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
|
|
6
|
+
type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-node' | 'duplicate-jsx-node' | 'split-jsx-sequence' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-to-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
|
|
7
7
|
type UndoEntrySnapshot = {
|
|
8
8
|
filePath: string;
|
|
9
9
|
oldContents: string | null;
|
|
@@ -55,6 +55,8 @@ type UndoEntry = {
|
|
|
55
55
|
entryType: 'delete-composition';
|
|
56
56
|
} | {
|
|
57
57
|
entryType: 'rename-composition';
|
|
58
|
+
} | {
|
|
59
|
+
entryType: 'update-composition-metadata';
|
|
58
60
|
} | {
|
|
59
61
|
entryType: 'new-composition';
|
|
60
62
|
} | {
|
package/dist/routes.js
CHANGED
|
@@ -278,6 +278,7 @@ const handleFallback = async ({ remotionRoot, hash, response, request, getCurren
|
|
|
278
278
|
title: 'Remotion Studio',
|
|
279
279
|
renderDefaults: getRenderDefaults(),
|
|
280
280
|
publicFolderExists: (0, node_fs_1.existsSync)(publicDir) ? publicDir : null,
|
|
281
|
+
fileSystemPlatform: process.platform,
|
|
281
282
|
gitSource,
|
|
282
283
|
projectName: (0, studio_shared_1.getProjectName)({
|
|
283
284
|
basename: node_path_1.default.basename,
|
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.
|
|
6
|
+
"version": "4.0.493",
|
|
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.
|
|
30
|
+
"remotion": "4.0.493",
|
|
31
31
|
"recast": "0.23.11",
|
|
32
|
-
"@remotion/bundler": "4.0.
|
|
33
|
-
"@remotion/renderer": "4.0.
|
|
34
|
-
"@remotion/studio-shared": "4.0.
|
|
32
|
+
"@remotion/bundler": "4.0.493",
|
|
33
|
+
"@remotion/renderer": "4.0.493",
|
|
34
|
+
"@remotion/studio-shared": "4.0.493",
|
|
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.
|
|
42
|
+
"@remotion/eslint-config-internal": "4.0.493",
|
|
43
43
|
"eslint": "9.19.0",
|
|
44
44
|
"@types/node": "20.12.14",
|
|
45
45
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|