@remotion/studio-server 4.0.495 → 4.0.497
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/better-opn/index.d.ts +6 -0
- package/dist/better-opn/index.js +46 -18
- package/dist/codemods/recast-mods.js +4 -15
- package/dist/codemods/strip-parenthesized-extra.d.ts +1 -0
- package/dist/codemods/strip-parenthesized-extra.js +16 -0
- package/dist/codemods/update-sequence-props/update-sequence-props.js +47 -0
- package/dist/helpers/css-shorthand-properties.d.ts +27 -0
- package/dist/helpers/css-shorthand-properties.js +43 -0
- package/dist/helpers/package-manager-spawn-options.d.ts +2 -0
- package/dist/helpers/package-manager-spawn-options.js +7 -0
- package/dist/helpers/parse-background-shorthand.d.ts +11 -0
- package/dist/helpers/parse-background-shorthand.js +41 -0
- package/dist/helpers/parse-border-shorthand.d.ts +6 -0
- package/dist/helpers/parse-border-shorthand.js +135 -0
- package/dist/helpers/resolve-composition-component.d.ts +3 -1
- package/dist/helpers/resolve-composition-component.js +40 -10
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/open-browser-shortcut.js +26 -16
- package/dist/preview-server/routes/can-update-sequence-props.js +54 -3
- package/dist/preview-server/routes/download-remote-asset.js +1 -0
- package/dist/preview-server/routes/insert-element.js +7 -1
- package/dist/preview-server/routes/insert-jsx-element.js +9 -1
- package/dist/preview-server/routes/install-dependency.js +5 -1
- package/dist/preview-server/routes/save-sequence-props.js +90 -22
- package/package.json +6 -6
- package/dist/preview-server/routes/delete-effect-keyframe.d.ts +0 -3
- package/dist/preview-server/routes/delete-effect-keyframe.js +0 -89
- package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +0 -3
- package/dist/preview-server/routes/delete-sequence-keyframe.js +0 -82
- package/dist/preview-server/routes/save-props-mutex.d.ts +0 -1
- package/dist/preview-server/routes/save-props-mutex.js +0 -11
|
@@ -44,6 +44,7 @@ const recast = __importStar(require("recast"));
|
|
|
44
44
|
const no_react_1 = require("remotion/no-react");
|
|
45
45
|
const format_file_content_1 = require("../codemods/format-file-content");
|
|
46
46
|
const parse_ast_1 = require("../codemods/parse-ast");
|
|
47
|
+
const strip_parenthesized_extra_1 = require("../codemods/strip-parenthesized-extra");
|
|
47
48
|
const update_nested_prop_1 = require("../codemods/update-nested-prop");
|
|
48
49
|
const imports_1 = require("./imports");
|
|
49
50
|
const svg_to_jsx_1 = require("./svg-to-jsx");
|
|
@@ -577,16 +578,18 @@ const createSolidElement = ({ localName, width, height, position, }) => {
|
|
|
577
578
|
createPositionAbsoluteStyleAttribute(position),
|
|
578
579
|
], true), null, []);
|
|
579
580
|
};
|
|
580
|
-
const createComponentElement = ({ addPositionStyle, localName, props, position, }) => {
|
|
581
|
+
const createComponentElement = ({ addPositionStyle, from, localName, props, position, }) => {
|
|
581
582
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
582
583
|
...props.map(createComponentProp),
|
|
584
|
+
...(from === null ? [] : [createNumberAttribute('from', from)]),
|
|
583
585
|
...(addPositionStyle
|
|
584
586
|
? [createPositionAbsoluteStyleAttribute(position)]
|
|
585
587
|
: []),
|
|
586
588
|
], true), null, []);
|
|
587
589
|
};
|
|
588
|
-
const createSequenceWrappedElement = ({ child, dimensions, durationInFrames, name, position, sequenceLocalName, }) => {
|
|
590
|
+
const createSequenceWrappedElement = ({ child, dimensions, durationInFrames, from, name, position, sequenceLocalName, }) => {
|
|
589
591
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(sequenceLocalName), [
|
|
592
|
+
...(from === null ? [] : [createNumberAttribute('from', from)]),
|
|
590
593
|
...(name === null ? [] : [createStringAttribute('name', name)]),
|
|
591
594
|
...(dimensions !== null
|
|
592
595
|
? [
|
|
@@ -600,22 +603,29 @@ const createSequenceWrappedElement = ({ child, dimensions, durationInFrames, nam
|
|
|
600
603
|
createPositionAbsoluteStyleAttribute(position),
|
|
601
604
|
], false), recast.types.builders.jsxClosingElement(recast.types.builders.jsxIdentifier(sequenceLocalName)), [child]);
|
|
602
605
|
};
|
|
603
|
-
const createAssetElement = ({ addPositionStyle, localName, staticFileLocalName, src, dimensions, position, }) => {
|
|
606
|
+
const createAssetElement = ({ addPositionStyle, durationInFrames, from, localName, staticFileLocalName, src, dimensions, position, }) => {
|
|
604
607
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
605
608
|
staticFileLocalName === null
|
|
606
609
|
? createStringSrcAttribute(src)
|
|
607
610
|
: createStaticFileSrcAttribute({ staticFileLocalName, src }),
|
|
611
|
+
...(durationInFrames === null
|
|
612
|
+
? []
|
|
613
|
+
: [createNumberAttribute('durationInFrames', durationInFrames)]),
|
|
614
|
+
...(from === null ? [] : [createNumberAttribute('from', from)]),
|
|
608
615
|
...(addPositionStyle
|
|
609
616
|
? [createAssetStyleAttribute({ dimensions, position })]
|
|
610
617
|
: []),
|
|
611
618
|
], true), null, []);
|
|
612
619
|
};
|
|
613
|
-
const createSvgElement = async ({ interactiveLocalName, markup, position, }) => {
|
|
620
|
+
const createSvgElement = async ({ from, interactiveLocalName, markup, position, }) => {
|
|
614
621
|
var _a;
|
|
615
622
|
var _b;
|
|
616
623
|
const svgElement = await (0, svg_to_jsx_1.svgMarkupToJsx)(markup);
|
|
617
624
|
const attributes = (_b = svgElement.openingElement.attributes) !== null && _b !== void 0 ? _b : [];
|
|
618
625
|
svgElement.openingElement.attributes = attributes;
|
|
626
|
+
if (from !== null) {
|
|
627
|
+
attributes.push(createNumberAttribute('from', from));
|
|
628
|
+
}
|
|
619
629
|
const styleAttribute = attributes.find((attribute) => attribute.type === 'JSXAttribute' &&
|
|
620
630
|
attribute.name.type === 'JSXIdentifier' &&
|
|
621
631
|
attribute.name.name === 'style');
|
|
@@ -1110,7 +1120,7 @@ const addElementToComponentRoot = ({ ast, exportName, element, }) => {
|
|
|
1110
1120
|
if (rootNode.type === 'JSXElement' && rootNode.openingElement.selfClosing) {
|
|
1111
1121
|
const fragment = recast.types.builders.jsxFragment(recast.types.builders.jsxOpeningFragment(), recast.types.builders.jsxClosingFragment(), [
|
|
1112
1122
|
createSequenceWithChild({
|
|
1113
|
-
child: rootNode,
|
|
1123
|
+
child: (0, strip_parenthesized_extra_1.stripParenthesizedExtra)(rootNode),
|
|
1114
1124
|
sequenceLocalName: ensureSequenceImport(ast),
|
|
1115
1125
|
}),
|
|
1116
1126
|
element,
|
|
@@ -1316,7 +1326,7 @@ const resolveCompositionComponent = async ({ remotionRoot, compositionFile, comp
|
|
|
1316
1326
|
};
|
|
1317
1327
|
};
|
|
1318
1328
|
exports.resolveCompositionComponent = resolveCompositionComponent;
|
|
1319
|
-
const createInsertableJsxElement = ({ addPositionStyleToComponent, ast, destinationFileName, element, remotionRoot, }) => {
|
|
1329
|
+
const createInsertableJsxElement = ({ addPositionStyleToComponent, ast, destinationFileName, element, from, remotionRoot, }) => {
|
|
1320
1330
|
if (element.type === 'solid') {
|
|
1321
1331
|
const solidLocalName = ensureSolidImport(ast);
|
|
1322
1332
|
return createSolidElement({
|
|
@@ -1335,6 +1345,7 @@ const createInsertableJsxElement = ({ addPositionStyleToComponent, ast, destinat
|
|
|
1335
1345
|
});
|
|
1336
1346
|
return createComponentElement({
|
|
1337
1347
|
addPositionStyle: addPositionStyleToComponent,
|
|
1348
|
+
from,
|
|
1338
1349
|
localName: componentLocalName,
|
|
1339
1350
|
props: element.props,
|
|
1340
1351
|
position: element.position,
|
|
@@ -1342,6 +1353,7 @@ const createInsertableJsxElement = ({ addPositionStyleToComponent, ast, destinat
|
|
|
1342
1353
|
}
|
|
1343
1354
|
if (element.type === 'svg') {
|
|
1344
1355
|
return createSvgElement({
|
|
1356
|
+
from,
|
|
1345
1357
|
interactiveLocalName: ensureInteractiveImport(ast),
|
|
1346
1358
|
markup: element.markup,
|
|
1347
1359
|
position: element.position,
|
|
@@ -1387,17 +1399,21 @@ const createInsertableJsxElement = ({ addPositionStyleToComponent, ast, destinat
|
|
|
1387
1399
|
throw new Error('Unsupported asset type');
|
|
1388
1400
|
}
|
|
1389
1401
|
return createAssetElement({
|
|
1390
|
-
addPositionStyle: element.assetType !== 'audio',
|
|
1402
|
+
addPositionStyle: addPositionStyleToComponent && element.assetType !== 'audio',
|
|
1403
|
+
durationInFrames: element.assetType === 'image' ? null : element.durationInFrames,
|
|
1404
|
+
from,
|
|
1391
1405
|
localName,
|
|
1392
1406
|
staticFileLocalName,
|
|
1393
1407
|
src: element.src,
|
|
1394
|
-
dimensions: element.
|
|
1408
|
+
dimensions: element.assetType === 'image' && from !== null
|
|
1409
|
+
? null
|
|
1410
|
+
: element.dimensions,
|
|
1395
1411
|
position: element.position,
|
|
1396
1412
|
});
|
|
1397
1413
|
}
|
|
1398
1414
|
throw new Error('Unsupported element type');
|
|
1399
1415
|
};
|
|
1400
|
-
const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile, compositionId, element, prettierConfigOverride, wrapInSequence = null, }) => {
|
|
1416
|
+
const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile, compositionId, element, from, prettierConfigOverride, wrapInSequence = null, }) => {
|
|
1401
1417
|
var _a;
|
|
1402
1418
|
const location = await (0, exports.resolveCompositionComponentWithFile)({
|
|
1403
1419
|
remotionRoot,
|
|
@@ -1422,13 +1438,26 @@ const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile,
|
|
|
1422
1438
|
durationInFrames: element.durationInFrames,
|
|
1423
1439
|
name: element.compositionId,
|
|
1424
1440
|
position: element.position,
|
|
1441
|
+
from,
|
|
1425
1442
|
}
|
|
1426
|
-
:
|
|
1443
|
+
: from === null ||
|
|
1444
|
+
element.type === 'asset' ||
|
|
1445
|
+
element.type === 'svg' ||
|
|
1446
|
+
element.type === 'component'
|
|
1447
|
+
? wrapInSequence
|
|
1448
|
+
: {
|
|
1449
|
+
dimensions: null,
|
|
1450
|
+
durationInFrames: null,
|
|
1451
|
+
name: null,
|
|
1452
|
+
position: element.position,
|
|
1453
|
+
from,
|
|
1454
|
+
};
|
|
1427
1455
|
const elementToInsert = await createInsertableJsxElement({
|
|
1428
1456
|
addPositionStyleToComponent: sequenceWrapper === null,
|
|
1429
1457
|
ast,
|
|
1430
1458
|
destinationFileName: location.fileName,
|
|
1431
1459
|
element,
|
|
1460
|
+
from,
|
|
1432
1461
|
remotionRoot,
|
|
1433
1462
|
});
|
|
1434
1463
|
const finalElementToInsert = sequenceWrapper
|
|
@@ -1436,6 +1465,7 @@ const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile,
|
|
|
1436
1465
|
child: elementToInsert,
|
|
1437
1466
|
dimensions: sequenceWrapper.dimensions,
|
|
1438
1467
|
durationInFrames: (_a = sequenceWrapper.durationInFrames) !== null && _a !== void 0 ? _a : null,
|
|
1468
|
+
from: sequenceWrapper.from,
|
|
1439
1469
|
name: sequenceWrapper.name,
|
|
1440
1470
|
position: sequenceWrapper.position,
|
|
1441
1471
|
sequenceLocalName: ensureSequenceImport(ast),
|
package/dist/index.d.ts
CHANGED
|
@@ -115,6 +115,7 @@ export declare const StudioServerInternals: {
|
|
|
115
115
|
version: string;
|
|
116
116
|
additionalArgs: string[];
|
|
117
117
|
}) => string[];
|
|
118
|
+
getPackageManagerSpawnOptions: () => Pick<import("child_process").SpawnOptionsWithoutStdio, "shell">;
|
|
118
119
|
addCompletedClientRender: ({ render, remotionRoot, }: {
|
|
119
120
|
render: import("@remotion/studio-shared").CompletedClientRender;
|
|
120
121
|
remotionRoot: string;
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ const file_watcher_1 = require("./file-watcher");
|
|
|
13
13
|
const get_latest_remotion_version_1 = require("./get-latest-remotion-version");
|
|
14
14
|
const get_installed_dependencies_1 = require("./helpers/get-installed-dependencies");
|
|
15
15
|
const install_command_1 = require("./helpers/install-command");
|
|
16
|
+
const package_manager_spawn_options_1 = require("./helpers/package-manager-spawn-options");
|
|
16
17
|
const max_timeline_tracks_1 = require("./max-timeline-tracks");
|
|
17
18
|
const get_package_manager_1 = require("./preview-server/get-package-manager");
|
|
18
19
|
const live_events_1 = require("./preview-server/live-events");
|
|
@@ -41,6 +42,7 @@ exports.StudioServerInternals = {
|
|
|
41
42
|
getInstalledDependencies: get_installed_dependencies_1.getInstalledDependencies,
|
|
42
43
|
getInstalledDependenciesWithVersions: get_installed_dependencies_1.getInstalledDependenciesWithVersions,
|
|
43
44
|
getInstallCommand: install_command_1.getInstallCommand,
|
|
45
|
+
getPackageManagerSpawnOptions: package_manager_spawn_options_1.getPackageManagerSpawnOptions,
|
|
44
46
|
addCompletedClientRender: client_render_queue_1.addCompletedClientRender,
|
|
45
47
|
getCompletedClientRenders: client_render_queue_1.getCompletedClientRenders,
|
|
46
48
|
removeCompletedClientRender: client_render_queue_1.removeCompletedClientRender,
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.registerOpenBrowserShortcut = void 0;
|
|
37
37
|
const readline = __importStar(require("node:readline"));
|
|
38
38
|
const renderer_1 = require("@remotion/renderer");
|
|
39
|
+
const better_opn_1 = require("./better-opn");
|
|
39
40
|
const maybe_open_browser_1 = require("./maybe-open-browser");
|
|
40
41
|
const live_events_1 = require("./preview-server/live-events");
|
|
41
42
|
const registerOpenBrowserShortcut = ({ browserArgs, browserFlag, url, logLevel, }) => {
|
|
@@ -64,30 +65,39 @@ const registerOpenBrowserShortcut = ({ browserArgs, browserFlag, url, logLevel,
|
|
|
64
65
|
process.stdin.pause();
|
|
65
66
|
}
|
|
66
67
|
};
|
|
67
|
-
const openStudio = () => {
|
|
68
|
+
const openStudio = async () => {
|
|
68
69
|
if (isOpeningBrowser) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
72
|
isOpeningBrowser = true;
|
|
72
73
|
(0, live_events_1.clearPrintPortMessageTimeout)();
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
try {
|
|
75
|
+
const didFocus = await (0, better_opn_1.focusBrowserTabByOrigin)({
|
|
76
|
+
url,
|
|
77
|
+
browserArgs,
|
|
78
|
+
browserFlag,
|
|
79
|
+
});
|
|
80
|
+
if (didFocus) {
|
|
81
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Opened ${url} in browser`));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const result = await (0, maybe_open_browser_1.maybeOpenBrowser)({
|
|
85
|
+
browserArgs,
|
|
86
|
+
browserFlag,
|
|
87
|
+
shouldOpenBrowser: true,
|
|
88
|
+
url,
|
|
89
|
+
logLevel,
|
|
90
|
+
});
|
|
81
91
|
if (result.didOpenBrowser) {
|
|
82
|
-
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `Opened ${url} in browser`);
|
|
92
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Opened ${url} in browser`));
|
|
83
93
|
}
|
|
84
|
-
}
|
|
85
|
-
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
86
96
|
renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, 'Could not open browser:', err);
|
|
87
|
-
}
|
|
88
|
-
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
89
99
|
isOpeningBrowser = false;
|
|
90
|
-
}
|
|
100
|
+
}
|
|
91
101
|
};
|
|
92
102
|
function onKeypress(_str, key) {
|
|
93
103
|
if ((key === null || key === void 0 ? void 0 : key.ctrl) && key.name === 'c') {
|
|
@@ -98,7 +108,7 @@ const registerOpenBrowserShortcut = ({ browserArgs, browserFlag, url, logLevel,
|
|
|
98
108
|
if ((key === null || key === void 0 ? void 0 : key.meta) || (key === null || key === void 0 ? void 0 : key.ctrl) || (key === null || key === void 0 ? void 0 : key.name) !== 's') {
|
|
99
109
|
return;
|
|
100
110
|
}
|
|
101
|
-
openStudio();
|
|
111
|
+
openStudio().catch(() => undefined);
|
|
102
112
|
}
|
|
103
113
|
readline.emitKeypressEvents(process.stdin);
|
|
104
114
|
process.stdin.setRawMode(true);
|
|
@@ -40,6 +40,7 @@ const studio_shared_1 = require("@remotion/studio-shared");
|
|
|
40
40
|
const recast = __importStar(require("recast"));
|
|
41
41
|
const no_react_1 = require("remotion/no-react");
|
|
42
42
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
43
|
+
const css_shorthand_properties_1 = require("../../helpers/css-shorthand-properties");
|
|
43
44
|
const get_ast_node_path_1 = require("../../helpers/get-ast-node-path");
|
|
44
45
|
const import_agnostic_node_path_1 = require("../../helpers/import-agnostic-node-path");
|
|
45
46
|
const parse_keyframe_easing_expression_1 = require("../../helpers/parse-keyframe-easing-expression");
|
|
@@ -669,6 +670,15 @@ const validateStyleValue = (childKey, value) => {
|
|
|
669
670
|
}
|
|
670
671
|
return true;
|
|
671
672
|
};
|
|
673
|
+
const getObjectPropertyName = (property) => {
|
|
674
|
+
if (property.key.type === 'Identifier') {
|
|
675
|
+
return property.key.name;
|
|
676
|
+
}
|
|
677
|
+
if (property.key.type === 'StringLiteral') {
|
|
678
|
+
return property.key.value;
|
|
679
|
+
}
|
|
680
|
+
return null;
|
|
681
|
+
};
|
|
672
682
|
const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfigValues, allowSpecialValues, }) => {
|
|
673
683
|
const attr = jsxElement.attributes.find((a) => a.type !== 'JSXSpreadAttribute' &&
|
|
674
684
|
a.name.type !== 'JSXNamespacedName' &&
|
|
@@ -687,9 +697,50 @@ const getNestedPropStatus = ({ jsxElement, ast, parentKey, childKey, videoConfig
|
|
|
687
697
|
return computedStatus();
|
|
688
698
|
}
|
|
689
699
|
const objExpr = expression;
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
700
|
+
const cssShorthand = (0, css_shorthand_properties_1.getCssShorthandForLonghand)({
|
|
701
|
+
parentKey,
|
|
702
|
+
longhand: childKey,
|
|
703
|
+
});
|
|
704
|
+
if (cssShorthand &&
|
|
705
|
+
objExpr.properties.some((property) => {
|
|
706
|
+
if (property.type !== 'ObjectProperty') {
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
const propertyName = getObjectPropertyName(property);
|
|
710
|
+
return (propertyName !== null &&
|
|
711
|
+
cssShorthand.isUnsupportedProperty(propertyName));
|
|
712
|
+
})) {
|
|
713
|
+
return computedStatus();
|
|
714
|
+
}
|
|
715
|
+
let prop;
|
|
716
|
+
for (let index = objExpr.properties.length - 1; index >= 0; index--) {
|
|
717
|
+
const candidate = objExpr.properties[index];
|
|
718
|
+
if (candidate.type === 'SpreadElement') {
|
|
719
|
+
return computedStatus();
|
|
720
|
+
}
|
|
721
|
+
if (candidate.type === 'ObjectProperty' &&
|
|
722
|
+
(getObjectPropertyName(candidate) === childKey ||
|
|
723
|
+
getObjectPropertyName(candidate) === (cssShorthand === null || cssShorthand === void 0 ? void 0 : cssShorthand.shorthand))) {
|
|
724
|
+
prop = candidate;
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
if (prop &&
|
|
729
|
+
cssShorthand &&
|
|
730
|
+
getObjectPropertyName(prop) === cssShorthand.shorthand) {
|
|
731
|
+
const shorthandValue = prop.value;
|
|
732
|
+
if (!(0, exports.isStaticValue)(shorthandValue, { allowSpecialValues: false })) {
|
|
733
|
+
return computedStatus();
|
|
734
|
+
}
|
|
735
|
+
const staticShorthandValue = (0, exports.extractStaticValue)(shorthandValue, {
|
|
736
|
+
allowSpecialValues: false,
|
|
737
|
+
});
|
|
738
|
+
if (typeof staticShorthandValue !== 'string') {
|
|
739
|
+
return computedStatus();
|
|
740
|
+
}
|
|
741
|
+
const parsed = cssShorthand.parse(staticShorthandValue);
|
|
742
|
+
return parsed ? staticStatus(parsed[childKey], null) : computedStatus();
|
|
743
|
+
}
|
|
693
744
|
if (!prop) {
|
|
694
745
|
// Property not set in the object, can be added
|
|
695
746
|
return staticStatus(undefined, null);
|
|
@@ -69,10 +69,14 @@ const validateElement = (element) => {
|
|
|
69
69
|
}
|
|
70
70
|
validateDimensions(element.dimensions);
|
|
71
71
|
};
|
|
72
|
-
const insertElementHandler = ({ input: { compositionFile, compositionId, element, position }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
72
|
+
const insertElementHandler = ({ input: { compositionFile, compositionId, element, from, position }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
73
73
|
try {
|
|
74
74
|
validateElement(element);
|
|
75
75
|
validatePosition(position);
|
|
76
|
+
if (from !== null &&
|
|
77
|
+
(!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
|
|
78
|
+
throw new Error('from must be a non-negative integer');
|
|
79
|
+
}
|
|
76
80
|
const componentName = (0, studio_shared_1.getElementComponentNameFromSourceCode)(element.sourceCode);
|
|
77
81
|
if (componentName === null) {
|
|
78
82
|
throw new Error('Element source must export exactly one named component');
|
|
@@ -118,9 +122,11 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
118
122
|
props: [],
|
|
119
123
|
position: null,
|
|
120
124
|
},
|
|
125
|
+
from: null,
|
|
121
126
|
prettierConfigOverride: null,
|
|
122
127
|
wrapInSequence: {
|
|
123
128
|
dimensions: element.dimensions,
|
|
129
|
+
from,
|
|
124
130
|
name: element.displayName,
|
|
125
131
|
position,
|
|
126
132
|
},
|
|
@@ -72,6 +72,9 @@ const validateElement = (element, remotionRoot) => {
|
|
|
72
72
|
validateDimension('width', element.dimensions.width);
|
|
73
73
|
validateDimension('height', element.dimensions.height);
|
|
74
74
|
}
|
|
75
|
+
if (element.durationInFrames !== null) {
|
|
76
|
+
validateDimension('durationInFrames', element.durationInFrames);
|
|
77
|
+
}
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
77
80
|
if (element.type === 'component') {
|
|
@@ -145,9 +148,13 @@ const getElementLabel = (element) => {
|
|
|
145
148
|
}
|
|
146
149
|
throw new Error('Unsupported element type');
|
|
147
150
|
};
|
|
148
|
-
const insertJsxElementHandler = ({ input: { compositionFile, compositionId, element }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
151
|
+
const insertJsxElementHandler = ({ input: { compositionFile, compositionId, element, from }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
149
152
|
try {
|
|
150
153
|
validateElement(element, remotionRoot);
|
|
154
|
+
if (from !== null &&
|
|
155
|
+
(!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
|
|
156
|
+
throw new Error('from must be a non-negative integer');
|
|
157
|
+
}
|
|
151
158
|
const elementLabel = getElementLabel(element);
|
|
152
159
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-jsx-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.type}"`);
|
|
153
160
|
const { fileName, source, oldContents, output, formatted, logLine } = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
|
|
@@ -155,6 +162,7 @@ const insertJsxElementHandler = ({ input: { compositionFile, compositionId, elem
|
|
|
155
162
|
compositionFile,
|
|
156
163
|
compositionId,
|
|
157
164
|
element,
|
|
165
|
+
from,
|
|
158
166
|
prettierConfigOverride: null,
|
|
159
167
|
});
|
|
160
168
|
(0, undo_stack_1.pushToUndoStack)({
|
|
@@ -6,6 +6,7 @@ const renderer_1 = require("@remotion/renderer");
|
|
|
6
6
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
7
7
|
const version_1 = require("remotion/version");
|
|
8
8
|
const install_command_1 = require("../../helpers/install-command");
|
|
9
|
+
const package_manager_spawn_options_1 = require("../../helpers/package-manager-spawn-options");
|
|
9
10
|
const get_package_manager_1 = require("../get-package-manager");
|
|
10
11
|
const getExtraPackageVersion = (packageName) => {
|
|
11
12
|
const pkg = studio_shared_1.extraPackages.find((p) => p.name === packageName);
|
|
@@ -52,7 +53,10 @@ const handleInstallPackage = async ({ logLevel, remotionRoot, input: { packageNa
|
|
|
52
53
|
const time = Date.now();
|
|
53
54
|
try {
|
|
54
55
|
await new Promise((resolve, reject) => {
|
|
55
|
-
const cmd = (0, node_child_process_1.spawn)(manager.manager, command,
|
|
56
|
+
const cmd = (0, node_child_process_1.spawn)(manager.manager, command, (0, package_manager_spawn_options_1.getPackageManagerSpawnOptions)());
|
|
57
|
+
cmd.on('error', (err) => {
|
|
58
|
+
reject(err);
|
|
59
|
+
});
|
|
56
60
|
cmd.stdout.on('data', (d) => {
|
|
57
61
|
const splitted = d.toString().trim().split('\n');
|
|
58
62
|
splitted.forEach((line) => {
|
|
@@ -59,14 +59,20 @@ const shouldSuppressHmrForSequencePropEdits = (edits) => {
|
|
|
59
59
|
(edit.sourceEdit === null || edit.sourceEdit === undefined));
|
|
60
60
|
};
|
|
61
61
|
exports.shouldSuppressHmrForSequencePropEdits = shouldSuppressHmrForSequencePropEdits;
|
|
62
|
-
const saveSequencePropsHandler = ({ input: { edits,
|
|
63
|
-
var _a, _b, _c;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const saveSequencePropsHandler = ({ input: { edits, addedKeyframes, movedKeyframes, clientId, undoLabel, redoLabel, }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
63
|
+
var _a, _b, _c, _d;
|
|
64
|
+
const keyframesToAdd = addedKeyframes === null ? [] : addedKeyframes;
|
|
65
|
+
const keyframesToMove = movedKeyframes === null
|
|
66
|
+
? { sequenceKeyframes: [], effectKeyframes: [] }
|
|
67
|
+
: movedKeyframes;
|
|
68
|
+
const totalKeyframeMoves = keyframesToMove.sequenceKeyframes.length +
|
|
69
|
+
keyframesToMove.effectKeyframes.length;
|
|
70
|
+
if (edits.length === 0 &&
|
|
71
|
+
keyframesToAdd.length === 0 &&
|
|
72
|
+
totalKeyframeMoves === 0) {
|
|
67
73
|
throw new Error('No sequence prop edits to save');
|
|
68
74
|
}
|
|
69
|
-
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-sequence-props] Received request with ${edits.length} edit(s) and ${totalKeyframeMoves} moved keyframe(s)`);
|
|
75
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[save-sequence-props] Received request with ${edits.length} edit(s), ${keyframesToAdd.length} added keyframe(s), and ${totalKeyframeMoves} moved keyframe(s)`);
|
|
70
76
|
const editGroups = new Map();
|
|
71
77
|
for (const [index, edit] of edits.entries()) {
|
|
72
78
|
const parsedValue = parseSequencePropEditValue(edit.value);
|
|
@@ -79,7 +85,8 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
79
85
|
const group = (_a = editGroups.get(absolutePath)) !== null && _a !== void 0 ? _a : {
|
|
80
86
|
fileRelativeToRoot,
|
|
81
87
|
edits: [],
|
|
82
|
-
|
|
88
|
+
addedKeyframes: [],
|
|
89
|
+
movedSequenceKeyframes: [],
|
|
83
90
|
effectKeyframes: [],
|
|
84
91
|
};
|
|
85
92
|
group.edits.push({
|
|
@@ -98,7 +105,7 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
98
105
|
});
|
|
99
106
|
editGroups.set(absolutePath, group);
|
|
100
107
|
}
|
|
101
|
-
for (const
|
|
108
|
+
for (const keyframe of keyframesToAdd) {
|
|
102
109
|
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
103
110
|
remotionRoot,
|
|
104
111
|
fileName: keyframe.fileName,
|
|
@@ -107,13 +114,14 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
107
114
|
const group = (_b = editGroups.get(absolutePath)) !== null && _b !== void 0 ? _b : {
|
|
108
115
|
fileRelativeToRoot,
|
|
109
116
|
edits: [],
|
|
110
|
-
|
|
117
|
+
addedKeyframes: [],
|
|
118
|
+
movedSequenceKeyframes: [],
|
|
111
119
|
effectKeyframes: [],
|
|
112
120
|
};
|
|
113
|
-
group.
|
|
121
|
+
group.addedKeyframes.push(keyframe);
|
|
114
122
|
editGroups.set(absolutePath, group);
|
|
115
123
|
}
|
|
116
|
-
for (const [index, keyframe] of
|
|
124
|
+
for (const [index, keyframe,] of keyframesToMove.sequenceKeyframes.entries()) {
|
|
117
125
|
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
118
126
|
remotionRoot,
|
|
119
127
|
fileName: keyframe.fileName,
|
|
@@ -122,7 +130,24 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
122
130
|
const group = (_c = editGroups.get(absolutePath)) !== null && _c !== void 0 ? _c : {
|
|
123
131
|
fileRelativeToRoot,
|
|
124
132
|
edits: [],
|
|
125
|
-
|
|
133
|
+
addedKeyframes: [],
|
|
134
|
+
movedSequenceKeyframes: [],
|
|
135
|
+
effectKeyframes: [],
|
|
136
|
+
};
|
|
137
|
+
group.movedSequenceKeyframes.push({ ...keyframe, index });
|
|
138
|
+
editGroups.set(absolutePath, group);
|
|
139
|
+
}
|
|
140
|
+
for (const [index, keyframe] of keyframesToMove.effectKeyframes.entries()) {
|
|
141
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
142
|
+
remotionRoot,
|
|
143
|
+
fileName: keyframe.fileName,
|
|
144
|
+
action: 'modify',
|
|
145
|
+
});
|
|
146
|
+
const group = (_d = editGroups.get(absolutePath)) !== null && _d !== void 0 ? _d : {
|
|
147
|
+
fileRelativeToRoot,
|
|
148
|
+
edits: [],
|
|
149
|
+
addedKeyframes: [],
|
|
150
|
+
movedSequenceKeyframes: [],
|
|
126
151
|
effectKeyframes: [],
|
|
127
152
|
};
|
|
128
153
|
group.effectKeyframes.push({ ...keyframe, index });
|
|
@@ -158,7 +183,40 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
158
183
|
});
|
|
159
184
|
}
|
|
160
185
|
}
|
|
161
|
-
for (const keyframeGroup of groupBy(group.
|
|
186
|
+
for (const keyframeGroup of groupBy(group.addedKeyframes, (keyframe) => JSON.stringify(keyframe.nodePath.nodePath))) {
|
|
187
|
+
const [firstSequenceKeyframe] = keyframeGroup;
|
|
188
|
+
if (!firstSequenceKeyframe) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const updates = keyframeGroup.map((keyframe) => ({
|
|
192
|
+
key: keyframe.key,
|
|
193
|
+
operation: {
|
|
194
|
+
type: 'add',
|
|
195
|
+
frame: keyframe.frame,
|
|
196
|
+
value: JSON.parse(keyframe.value),
|
|
197
|
+
},
|
|
198
|
+
}));
|
|
199
|
+
const result = await (0, update_keyframes_1.updateSequenceKeyframes)({
|
|
200
|
+
input: output,
|
|
201
|
+
nodePath: firstSequenceKeyframe.nodePath.nodePath,
|
|
202
|
+
schema: firstSequenceKeyframe.schema,
|
|
203
|
+
videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
|
|
204
|
+
updates,
|
|
205
|
+
});
|
|
206
|
+
output = result.output;
|
|
207
|
+
firstLogLine = Math.min(firstLogLine, result.logLine);
|
|
208
|
+
for (const [updateIndex, update] of updates.entries()) {
|
|
209
|
+
sequenceKeyframeLogs.push({
|
|
210
|
+
fileRelativeToRoot: group.fileRelativeToRoot,
|
|
211
|
+
line: result.logLine,
|
|
212
|
+
key: update.key,
|
|
213
|
+
oldValueString: result.oldValueStrings[updateIndex],
|
|
214
|
+
newValueString: result.newValueStrings[updateIndex],
|
|
215
|
+
formatted: result.formatted,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
for (const keyframeGroup of groupBy(group.movedSequenceKeyframes, (keyframe) => JSON.stringify(keyframe.nodePath.nodePath))) {
|
|
162
220
|
const [firstSequenceKeyframe] = keyframeGroup;
|
|
163
221
|
if (!firstSequenceKeyframe) {
|
|
164
222
|
continue;
|
|
@@ -318,10 +376,16 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
318
376
|
});
|
|
319
377
|
}
|
|
320
378
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
321
|
-
const
|
|
379
|
+
const statusTargets = [
|
|
380
|
+
...new Map([...edits, ...keyframesToAdd].map((target) => [
|
|
381
|
+
JSON.stringify(target.nodePath),
|
|
382
|
+
target,
|
|
383
|
+
])).values(),
|
|
384
|
+
];
|
|
385
|
+
const results = statusTargets.map((target) => {
|
|
322
386
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
323
387
|
remotionRoot,
|
|
324
|
-
fileName:
|
|
388
|
+
fileName: target.fileName,
|
|
325
389
|
action: 'modify',
|
|
326
390
|
});
|
|
327
391
|
const output = outputByPath.get(absolutePath);
|
|
@@ -330,22 +394,26 @@ const saveSequencePropsHandler = ({ input: { edits, movedKeyframes = { sequenceK
|
|
|
330
394
|
}
|
|
331
395
|
const newStatus = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
|
|
332
396
|
fileContents: output,
|
|
333
|
-
keys: (0, studio_shared_1.getAllSchemaKeys)(
|
|
334
|
-
assetKeys: (0, studio_shared_1.getAssetSchemaKeys)(
|
|
335
|
-
nodePath:
|
|
397
|
+
keys: (0, studio_shared_1.getAllSchemaKeys)(target.schema),
|
|
398
|
+
assetKeys: (0, studio_shared_1.getAssetSchemaKeys)(target.schema),
|
|
399
|
+
nodePath: target.nodePath.nodePath,
|
|
336
400
|
componentIdentity: null,
|
|
337
401
|
effects: [],
|
|
338
|
-
videoConfigValues:
|
|
402
|
+
videoConfigValues: target.nodePath.videoConfigValues,
|
|
339
403
|
});
|
|
340
404
|
return {
|
|
341
|
-
fileName:
|
|
342
|
-
nodePath:
|
|
405
|
+
fileName: target.fileName,
|
|
406
|
+
nodePath: target.nodePath,
|
|
343
407
|
props: newStatus.props,
|
|
344
408
|
};
|
|
345
409
|
});
|
|
410
|
+
const firstResult = results[0];
|
|
411
|
+
if (!firstResult) {
|
|
412
|
+
throw new Error('Could not compute sequence prop edit status');
|
|
413
|
+
}
|
|
346
414
|
return {
|
|
347
415
|
canUpdate: true,
|
|
348
|
-
props:
|
|
416
|
+
props: firstResult.props,
|
|
349
417
|
results,
|
|
350
418
|
};
|
|
351
419
|
});
|
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.497",
|
|
7
7
|
"description": "Run a Remotion Studio with a server backend",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"kiwi-schema": "0.5.0",
|
|
31
31
|
"semver": "7.5.3",
|
|
32
32
|
"prettier": "3.8.1",
|
|
33
|
-
"remotion": "4.0.
|
|
33
|
+
"remotion": "4.0.497",
|
|
34
34
|
"recast": "0.23.11",
|
|
35
|
-
"@remotion/bundler": "4.0.
|
|
36
|
-
"@remotion/renderer": "4.0.
|
|
37
|
-
"@remotion/studio-shared": "4.0.
|
|
35
|
+
"@remotion/bundler": "4.0.497",
|
|
36
|
+
"@remotion/renderer": "4.0.497",
|
|
37
|
+
"@remotion/studio-shared": "4.0.497",
|
|
38
38
|
"memfs": "3.4.3",
|
|
39
39
|
"open": "8.4.2"
|
|
40
40
|
},
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"ast-types": "0.16.1",
|
|
43
43
|
"react": "19.2.3",
|
|
44
44
|
"@types/semver": "7.5.3",
|
|
45
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
45
|
+
"@remotion/eslint-config-internal": "4.0.497",
|
|
46
46
|
"eslint": "9.19.0",
|
|
47
47
|
"@types/node": "20.12.14",
|
|
48
48
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse } from '@remotion/studio-shared';
|
|
2
|
-
import type { ApiHandler } from '../api-types';
|
|
3
|
-
export declare const deleteEffectKeyframeHandler: ApiHandler<DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse>;
|