@remotion/studio-server 4.0.470 → 4.0.471
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/add-effect.d.ts +15 -0
- package/dist/codemods/add-effect.js +231 -0
- package/dist/codemods/reorder-effect.d.ts +13 -0
- package/dist/codemods/reorder-effect.js +61 -0
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +4 -0
- package/dist/codemods/update-keyframes/update-keyframes.js +25 -10
- package/dist/helpers/open-in-editor.d.ts +2 -2
- package/dist/helpers/open-in-editor.js +35 -2
- package/dist/helpers/resolve-composition-component.d.ts +15 -0
- package/dist/helpers/resolve-composition-component.js +269 -31
- package/dist/preview-server/api-routes.js +8 -4
- package/dist/preview-server/routes/add-effect-keyframe.js +2 -2
- package/dist/preview-server/routes/add-effect.d.ts +3 -0
- package/dist/preview-server/routes/add-effect.js +68 -0
- package/dist/preview-server/routes/add-sequence-keyframe.js +6 -3
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +1 -0
- package/dist/preview-server/routes/can-update-sequence-props.js +15 -1
- package/dist/preview-server/routes/delete-keyframes.d.ts +13 -0
- package/dist/preview-server/routes/delete-keyframes.js +263 -0
- package/dist/preview-server/routes/insert-jsx-element.d.ts +3 -0
- package/dist/preview-server/routes/insert-jsx-element.js +79 -0
- package/dist/preview-server/routes/reorder-effect.d.ts +3 -0
- package/dist/preview-server/routes/reorder-effect.js +67 -0
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +2 -1
- package/dist/preview-server/sequence-props-watchers.d.ts +2 -1
- package/dist/preview-server/sequence-props-watchers.js +22 -2
- package/dist/preview-server/undo-stack.d.ts +9 -1
- package/package.json +6 -6
|
@@ -36,10 +36,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.resolveCompositionComponent = void 0;
|
|
39
|
+
exports.insertJsxElementIntoComposition = exports.resolveCompositionComponent = void 0;
|
|
40
40
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const node_path_1 = __importDefault(require("node:path"));
|
|
42
42
|
const recast = __importStar(require("recast"));
|
|
43
|
+
const format_file_content_1 = require("../codemods/format-file-content");
|
|
43
44
|
const parse_ast_1 = require("../codemods/parse-ast");
|
|
44
45
|
const allowedFileExtensions = new Set(['.tsx', '.ts', '.jsx', '.js']);
|
|
45
46
|
const extensionsToProbe = ['.tsx', '.ts', '.jsx', '.js'];
|
|
@@ -503,6 +504,205 @@ const getComponentRootNode = (declaration) => {
|
|
|
503
504
|
const createSequenceElement = () => {
|
|
504
505
|
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier('Sequence'), []), recast.types.builders.jsxClosingElement(recast.types.builders.jsxIdentifier('Sequence')), []);
|
|
505
506
|
};
|
|
507
|
+
const createNumberAttribute = (name, value) => {
|
|
508
|
+
return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.numericLiteral(value)));
|
|
509
|
+
};
|
|
510
|
+
const createSolidElement = ({ localName, width, height, }) => {
|
|
511
|
+
return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
|
|
512
|
+
createNumberAttribute('width', width),
|
|
513
|
+
createNumberAttribute('height', height),
|
|
514
|
+
recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('style'), recast.types.builders.jsxExpressionContainer(recast.types.builders.objectExpression([
|
|
515
|
+
recast.types.builders.objectProperty(recast.types.builders.identifier('position'), recast.types.builders.stringLiteral('absolute')),
|
|
516
|
+
]))),
|
|
517
|
+
], true), null, []);
|
|
518
|
+
};
|
|
519
|
+
const createFragmentWithElement = (element) => {
|
|
520
|
+
return recast.types.builders.jsxFragment(recast.types.builders.jsxOpeningFragment(), recast.types.builders.jsxClosingFragment(), [element]);
|
|
521
|
+
};
|
|
522
|
+
const replaceNullReturnInFunctionLike = ({ fn, element, }) => {
|
|
523
|
+
var _a, _b;
|
|
524
|
+
var _c, _d;
|
|
525
|
+
if (fn.type === 'ArrowFunctionExpression' && fn.body.type === 'NullLiteral') {
|
|
526
|
+
fn.body = createFragmentWithElement(element);
|
|
527
|
+
return (_c = (_a = fn.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _c !== void 0 ? _c : 1;
|
|
528
|
+
}
|
|
529
|
+
if (fn.body.type !== 'BlockStatement') {
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
const returnStatement = getTopLevelReturnStatement(fn.body.body);
|
|
533
|
+
if (!(returnStatement === null || returnStatement === void 0 ? void 0 : returnStatement.argument) ||
|
|
534
|
+
returnStatement.argument.type !== 'NullLiteral') {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
returnStatement.argument = createFragmentWithElement(element);
|
|
538
|
+
return (_d = (_b = returnStatement.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _d !== void 0 ? _d : 1;
|
|
539
|
+
};
|
|
540
|
+
const addElementToNullComponentReturn = ({ declaration, element, }) => {
|
|
541
|
+
var _a;
|
|
542
|
+
var _b;
|
|
543
|
+
if (declaration.type === 'VariableDeclarator') {
|
|
544
|
+
if (!declaration.init ||
|
|
545
|
+
(declaration.init.type !== 'ArrowFunctionExpression' &&
|
|
546
|
+
declaration.init.type !== 'FunctionExpression')) {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
return replaceNullReturnInFunctionLike({ fn: declaration.init, element });
|
|
550
|
+
}
|
|
551
|
+
if (declaration.type === 'ArrowFunctionExpression' ||
|
|
552
|
+
declaration.type === 'FunctionExpression' ||
|
|
553
|
+
declaration.type === 'FunctionDeclaration') {
|
|
554
|
+
return replaceNullReturnInFunctionLike({ fn: declaration, element });
|
|
555
|
+
}
|
|
556
|
+
if (declaration.type !== 'ClassDeclaration') {
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
const renderMethod = findRenderMethod(declaration);
|
|
560
|
+
if (!renderMethod) {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
const returnStatement = getTopLevelReturnStatement(renderMethod.body.body);
|
|
564
|
+
if (!(returnStatement === null || returnStatement === void 0 ? void 0 : returnStatement.argument) ||
|
|
565
|
+
returnStatement.argument.type !== 'NullLiteral') {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
returnStatement.argument = createFragmentWithElement(element);
|
|
569
|
+
return (_b = (_a = returnStatement.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _b !== void 0 ? _b : 1;
|
|
570
|
+
};
|
|
571
|
+
const getImportedName = (specifier) => {
|
|
572
|
+
if (specifier.imported.type === 'Identifier') {
|
|
573
|
+
return specifier.imported.name;
|
|
574
|
+
}
|
|
575
|
+
return specifier.imported.value;
|
|
576
|
+
};
|
|
577
|
+
const declarationBindsName = (declaration, name) => {
|
|
578
|
+
var _a;
|
|
579
|
+
if (declaration.type === 'FunctionDeclaration' ||
|
|
580
|
+
declaration.type === 'ClassDeclaration') {
|
|
581
|
+
return ((_a = declaration.id) === null || _a === void 0 ? void 0 : _a.name) === name;
|
|
582
|
+
}
|
|
583
|
+
return declaration.declarations.some((variableDeclaration) => {
|
|
584
|
+
return (variableDeclaration.id.type === 'Identifier' &&
|
|
585
|
+
variableDeclaration.id.name === name);
|
|
586
|
+
});
|
|
587
|
+
};
|
|
588
|
+
const hasTopLevelBinding = ({ ast, name }) => {
|
|
589
|
+
return ast.program.body.some((node) => {
|
|
590
|
+
var _a;
|
|
591
|
+
if (node.type === 'FunctionDeclaration' ||
|
|
592
|
+
node.type === 'ClassDeclaration' ||
|
|
593
|
+
node.type === 'VariableDeclaration') {
|
|
594
|
+
return declarationBindsName(node, name);
|
|
595
|
+
}
|
|
596
|
+
if (node.type === 'ExportNamedDeclaration' &&
|
|
597
|
+
node.declaration &&
|
|
598
|
+
(node.declaration.type === 'FunctionDeclaration' ||
|
|
599
|
+
node.declaration.type === 'ClassDeclaration' ||
|
|
600
|
+
node.declaration.type === 'VariableDeclaration')) {
|
|
601
|
+
return declarationBindsName(node.declaration, name);
|
|
602
|
+
}
|
|
603
|
+
if (node.type !== 'ImportDeclaration') {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
return (_a = node.specifiers) === null || _a === void 0 ? void 0 : _a.some((specifier) => {
|
|
607
|
+
var _a;
|
|
608
|
+
return ((_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) === name;
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
};
|
|
612
|
+
const getAvailableSolidLocalName = (ast) => {
|
|
613
|
+
const candidates = ['Solid', 'RemotionSolid'];
|
|
614
|
+
const available = candidates.find((candidate) => {
|
|
615
|
+
return !hasTopLevelBinding({ ast, name: candidate });
|
|
616
|
+
});
|
|
617
|
+
if (!available) {
|
|
618
|
+
throw new Error('Cannot add <Solid> because Solid is already defined');
|
|
619
|
+
}
|
|
620
|
+
return available;
|
|
621
|
+
};
|
|
622
|
+
const insertImportDeclaration = (ast, importDeclaration) => {
|
|
623
|
+
const { body } = ast.program;
|
|
624
|
+
let lastImportIndex = -1;
|
|
625
|
+
for (let i = 0; i < body.length; i++) {
|
|
626
|
+
if (body[i].type === 'ImportDeclaration') {
|
|
627
|
+
lastImportIndex = i;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
body.splice(lastImportIndex + 1, 0, importDeclaration);
|
|
631
|
+
};
|
|
632
|
+
const addSolidImport = ({ ast, localName, remotionImport, }) => {
|
|
633
|
+
var _a;
|
|
634
|
+
var _b;
|
|
635
|
+
const imported = recast.types.builders.identifier('Solid');
|
|
636
|
+
const local = localName === 'Solid' ? null : recast.types.builders.identifier(localName);
|
|
637
|
+
const specifier = recast.types.builders.importSpecifier(imported, local);
|
|
638
|
+
const canAddToExistingRemotionImport = remotionImport &&
|
|
639
|
+
!((_a = remotionImport.specifiers) === null || _a === void 0 ? void 0 : _a.some((importSpecifier) => importSpecifier.type === 'ImportNamespaceSpecifier'));
|
|
640
|
+
if (canAddToExistingRemotionImport) {
|
|
641
|
+
remotionImport.specifiers = [
|
|
642
|
+
...((_b = remotionImport.specifiers) !== null && _b !== void 0 ? _b : []),
|
|
643
|
+
specifier,
|
|
644
|
+
];
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
const importDeclaration = recast.types.builders.importDeclaration([], recast.types.builders.stringLiteral('remotion'));
|
|
648
|
+
importDeclaration.specifiers = [specifier];
|
|
649
|
+
insertImportDeclaration(ast, importDeclaration);
|
|
650
|
+
};
|
|
651
|
+
const ensureSolidImport = (ast) => {
|
|
652
|
+
var _a, _b;
|
|
653
|
+
let remotionImport = null;
|
|
654
|
+
for (const node of ast.program.body) {
|
|
655
|
+
if (node.type !== 'ImportDeclaration' || node.source.value !== 'remotion') {
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
remotionImport = node;
|
|
659
|
+
const solidSpecifier = (_a = node.specifiers) === null || _a === void 0 ? void 0 : _a.find((specifier) => {
|
|
660
|
+
return (specifier.type === 'ImportSpecifier' &&
|
|
661
|
+
getImportedName(specifier) === 'Solid');
|
|
662
|
+
});
|
|
663
|
+
if ((_b = solidSpecifier === null || solidSpecifier === void 0 ? void 0 : solidSpecifier.local) === null || _b === void 0 ? void 0 : _b.name) {
|
|
664
|
+
return solidSpecifier.local.name;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const localName = getAvailableSolidLocalName(ast);
|
|
668
|
+
addSolidImport({ ast, localName, remotionImport });
|
|
669
|
+
return localName;
|
|
670
|
+
};
|
|
671
|
+
const addElementToComponentRoot = ({ ast, exportName, element, }) => {
|
|
672
|
+
var _a;
|
|
673
|
+
var _b;
|
|
674
|
+
const declaration = getDeclarationByExportName({ ast, exportName });
|
|
675
|
+
if (!declaration) {
|
|
676
|
+
throw new Error('Could not find composition component declaration');
|
|
677
|
+
}
|
|
678
|
+
const rootNode = getComponentRootNode(declaration);
|
|
679
|
+
if (!rootNode) {
|
|
680
|
+
const insertedAt = addElementToNullComponentReturn({ declaration, element });
|
|
681
|
+
if (insertedAt !== null) {
|
|
682
|
+
return insertedAt;
|
|
683
|
+
}
|
|
684
|
+
throw new Error('Composition component does not return JSX');
|
|
685
|
+
}
|
|
686
|
+
if (rootNode.type === 'JSXElement' && rootNode.openingElement.selfClosing) {
|
|
687
|
+
throw new Error('Cannot insert into a self-closing root JSX element');
|
|
688
|
+
}
|
|
689
|
+
const CANVAS_ROOT_ELEMENTS = [
|
|
690
|
+
'ThreeCanvas',
|
|
691
|
+
'RiveCanvas',
|
|
692
|
+
'SkiaCanvas',
|
|
693
|
+
'canvas',
|
|
694
|
+
];
|
|
695
|
+
if (rootNode.type === 'JSXElement' &&
|
|
696
|
+
rootNode.openingElement.name.type === 'JSXIdentifier' &&
|
|
697
|
+
CANVAS_ROOT_ELEMENTS.includes(rootNode.openingElement.name.name)) {
|
|
698
|
+
throw new Error(`Cannot insert a <Solid> into a composition whose root element is <${rootNode.openingElement.name.name}>`);
|
|
699
|
+
}
|
|
700
|
+
if (!rootNode.children) {
|
|
701
|
+
throw new Error('Composition component root does not accept children');
|
|
702
|
+
}
|
|
703
|
+
rootNode.children.push(element);
|
|
704
|
+
return (_b = (_a = rootNode.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _b !== void 0 ? _b : 1;
|
|
705
|
+
};
|
|
506
706
|
const getDefaultExportDeclaration = (ast) => {
|
|
507
707
|
let declaration = null;
|
|
508
708
|
let identifierName = null;
|
|
@@ -532,39 +732,16 @@ const getDeclarationByExportName = ({ ast, exportName, }) => {
|
|
|
532
732
|
return findLocalComponentDeclaration({ ast, name: exportName });
|
|
533
733
|
};
|
|
534
734
|
const canAddSequenceToComponent = ({ ast, exportName, }) => {
|
|
535
|
-
const declaration = getDeclarationByExportName({ ast, exportName });
|
|
536
|
-
if (!declaration) {
|
|
537
|
-
return false;
|
|
538
|
-
}
|
|
539
|
-
const rootNode = getComponentRootNode(declaration);
|
|
540
|
-
if (!rootNode) {
|
|
541
|
-
return false;
|
|
542
|
-
}
|
|
543
|
-
if (rootNode.type === 'JSXElement') {
|
|
544
|
-
if (rootNode.openingElement.selfClosing) {
|
|
545
|
-
return false;
|
|
546
|
-
}
|
|
547
|
-
if (!rootNode.children) {
|
|
548
|
-
return false;
|
|
549
|
-
}
|
|
550
|
-
rootNode.children.push(createSequenceElement());
|
|
551
|
-
try {
|
|
552
|
-
recast.print(ast);
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
catch (_a) {
|
|
556
|
-
return false;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (!rootNode.children) {
|
|
560
|
-
return false;
|
|
561
|
-
}
|
|
562
|
-
rootNode.children.push(createSequenceElement());
|
|
563
735
|
try {
|
|
736
|
+
addElementToComponentRoot({
|
|
737
|
+
ast,
|
|
738
|
+
exportName,
|
|
739
|
+
element: createSequenceElement(),
|
|
740
|
+
});
|
|
564
741
|
recast.print(ast);
|
|
565
742
|
return true;
|
|
566
743
|
}
|
|
567
|
-
catch (
|
|
744
|
+
catch (_a) {
|
|
568
745
|
return false;
|
|
569
746
|
}
|
|
570
747
|
};
|
|
@@ -582,6 +759,8 @@ const getComponentLocationInFile = async ({ remotionRoot, fileName, exportName,
|
|
|
582
759
|
});
|
|
583
760
|
return {
|
|
584
761
|
source: node_path_1.default.relative(remotionRoot, fileName),
|
|
762
|
+
fileName,
|
|
763
|
+
exportName,
|
|
585
764
|
line: (_a = location === null || location === void 0 ? void 0 : location.line) !== null && _a !== void 0 ? _a : 1,
|
|
586
765
|
column: (_b = location === null || location === void 0 ? void 0 : location.column) !== null && _b !== void 0 ? _b : 0,
|
|
587
766
|
canAddSequence,
|
|
@@ -641,7 +820,7 @@ const getComponentLocationRecursively = async ({ remotionRoot, fileName, exportN
|
|
|
641
820
|
visited.delete(key);
|
|
642
821
|
}
|
|
643
822
|
};
|
|
644
|
-
const
|
|
823
|
+
const resolveCompositionComponentWithFile = async ({ remotionRoot, compositionFile, compositionId, }) => {
|
|
645
824
|
const compositionFileName = node_path_1.default.resolve(remotionRoot, compositionFile);
|
|
646
825
|
const input = await readSourceFile({
|
|
647
826
|
remotionRoot,
|
|
@@ -688,4 +867,63 @@ const resolveCompositionComponent = async ({ remotionRoot, compositionFile, comp
|
|
|
688
867
|
visited: new Set(),
|
|
689
868
|
});
|
|
690
869
|
};
|
|
870
|
+
const resolveCompositionComponent = async ({ remotionRoot, compositionFile, compositionId, }) => {
|
|
871
|
+
const { source, line, column, canAddSequence } = await resolveCompositionComponentWithFile({
|
|
872
|
+
remotionRoot,
|
|
873
|
+
compositionFile,
|
|
874
|
+
compositionId,
|
|
875
|
+
});
|
|
876
|
+
return {
|
|
877
|
+
source,
|
|
878
|
+
line,
|
|
879
|
+
column,
|
|
880
|
+
canAddSequence,
|
|
881
|
+
};
|
|
882
|
+
};
|
|
691
883
|
exports.resolveCompositionComponent = resolveCompositionComponent;
|
|
884
|
+
const createInsertableJsxElement = ({ ast, element, }) => {
|
|
885
|
+
if (element.type === 'solid') {
|
|
886
|
+
const solidLocalName = ensureSolidImport(ast);
|
|
887
|
+
return createSolidElement({
|
|
888
|
+
localName: solidLocalName,
|
|
889
|
+
width: element.width,
|
|
890
|
+
height: element.height,
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
throw new Error('Unsupported element type');
|
|
894
|
+
};
|
|
895
|
+
const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile, compositionId, element, prettierConfigOverride, }) => {
|
|
896
|
+
const location = await resolveCompositionComponentWithFile({
|
|
897
|
+
remotionRoot,
|
|
898
|
+
compositionFile,
|
|
899
|
+
compositionId,
|
|
900
|
+
});
|
|
901
|
+
if (!location.canAddSequence) {
|
|
902
|
+
throw new Error('Cannot insert JSX element into this composition component');
|
|
903
|
+
}
|
|
904
|
+
const input = await readSourceFile({
|
|
905
|
+
remotionRoot,
|
|
906
|
+
fileName: location.fileName,
|
|
907
|
+
});
|
|
908
|
+
const ast = (0, parse_ast_1.parseAst)(input);
|
|
909
|
+
const elementToInsert = createInsertableJsxElement({ ast, element });
|
|
910
|
+
const logLine = addElementToComponentRoot({
|
|
911
|
+
ast,
|
|
912
|
+
exportName: location.exportName,
|
|
913
|
+
element: elementToInsert,
|
|
914
|
+
});
|
|
915
|
+
const finalFile = (0, parse_ast_1.serializeAst)(ast);
|
|
916
|
+
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
917
|
+
input: finalFile,
|
|
918
|
+
prettierConfigOverride,
|
|
919
|
+
});
|
|
920
|
+
return {
|
|
921
|
+
fileName: location.fileName,
|
|
922
|
+
source: location.source,
|
|
923
|
+
oldContents: input,
|
|
924
|
+
output,
|
|
925
|
+
formatted,
|
|
926
|
+
logLine,
|
|
927
|
+
};
|
|
928
|
+
};
|
|
929
|
+
exports.insertJsxElementIntoComposition = insertJsxElementIntoComposition;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.allApiRoutes = void 0;
|
|
4
|
+
const add_effect_1 = require("./routes/add-effect");
|
|
4
5
|
const add_effect_keyframe_1 = require("./routes/add-effect-keyframe");
|
|
5
6
|
const add_render_1 = require("./routes/add-render");
|
|
6
7
|
const add_sequence_keyframe_1 = require("./routes/add-sequence-keyframe");
|
|
@@ -9,11 +10,11 @@ const apply_visual_control_change_1 = require("./routes/apply-visual-control-cha
|
|
|
9
10
|
const cancel_render_1 = require("./routes/cancel-render");
|
|
10
11
|
const composition_component_info_1 = require("./routes/composition-component-info");
|
|
11
12
|
const delete_effect_1 = require("./routes/delete-effect");
|
|
12
|
-
const delete_effect_keyframe_1 = require("./routes/delete-effect-keyframe");
|
|
13
13
|
const delete_jsx_node_1 = require("./routes/delete-jsx-node");
|
|
14
|
-
const
|
|
14
|
+
const delete_keyframes_1 = require("./routes/delete-keyframes");
|
|
15
15
|
const delete_static_file_1 = require("./routes/delete-static-file");
|
|
16
16
|
const duplicate_jsx_node_1 = require("./routes/duplicate-jsx-node");
|
|
17
|
+
const insert_jsx_element_1 = require("./routes/insert-jsx-element");
|
|
17
18
|
const install_dependency_1 = require("./routes/install-dependency");
|
|
18
19
|
const open_in_editor_1 = require("./routes/open-in-editor");
|
|
19
20
|
const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
|
|
@@ -21,6 +22,7 @@ const project_info_1 = require("./routes/project-info");
|
|
|
21
22
|
const redo_1 = require("./routes/redo");
|
|
22
23
|
const register_client_render_1 = require("./routes/register-client-render");
|
|
23
24
|
const remove_render_1 = require("./routes/remove-render");
|
|
25
|
+
const reorder_effect_1 = require("./routes/reorder-effect");
|
|
24
26
|
const restart_studio_1 = require("./routes/restart-studio");
|
|
25
27
|
const save_effect_props_1 = require("./routes/save-effect-props");
|
|
26
28
|
const save_sequence_props_1 = require("./routes/save-sequence-props");
|
|
@@ -54,9 +56,10 @@ exports.allApiRoutes = {
|
|
|
54
56
|
'/api/unsubscribe-from-sequence-props': unsubscribe_from_sequence_props_1.unsubscribeFromSequenceProps,
|
|
55
57
|
'/api/save-sequence-props': save_sequence_props_1.saveSequencePropsHandler,
|
|
56
58
|
'/api/save-effect-props': save_effect_props_1.saveEffectPropsHandler,
|
|
57
|
-
'/api/
|
|
59
|
+
'/api/add-effect': add_effect_1.addEffectHandler,
|
|
60
|
+
'/api/reorder-effect': reorder_effect_1.reorderEffectHandler,
|
|
61
|
+
'/api/delete-keyframes': delete_keyframes_1.deleteKeyframesHandler,
|
|
58
62
|
'/api/add-sequence-keyframe': add_sequence_keyframe_1.addSequenceKeyframeHandler,
|
|
59
|
-
'/api/delete-effect-keyframe': delete_effect_keyframe_1.deleteEffectKeyframeHandler,
|
|
60
63
|
'/api/add-effect-keyframe': add_effect_keyframe_1.addEffectKeyframeHandler,
|
|
61
64
|
'/api/delete-effect': delete_effect_1.deleteEffectHandler,
|
|
62
65
|
'/api/delete-jsx-node': delete_jsx_node_1.deleteJsxNodeHandler,
|
|
@@ -66,6 +69,7 @@ exports.allApiRoutes = {
|
|
|
66
69
|
'/api/delete-static-file': delete_static_file_1.deleteStaticFileHandler,
|
|
67
70
|
'/api/restart-studio': restart_studio_1.handleRestartStudio,
|
|
68
71
|
'/api/install-package': install_dependency_1.handleInstallPackage,
|
|
72
|
+
'/api/insert-jsx-element': insert_jsx_element_1.insertJsxElementHandler,
|
|
69
73
|
'/api/undo': undo_1.undoHandler,
|
|
70
74
|
'/api/redo': redo_1.redoHandler,
|
|
71
75
|
};
|
|
@@ -23,7 +23,7 @@ const addEffectKeyframeHandler = ({ input: { fileName, sequenceNodePath, effectI
|
|
|
23
23
|
});
|
|
24
24
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
25
25
|
const parsedValue = JSON.parse(value);
|
|
26
|
-
const { output, oldValueStrings, newValueStrings, formatted, logLine, effectCallee, } = await (0, update_keyframes_1.updateEffectKeyframes)({
|
|
26
|
+
const { output, oldValueStrings, newValueStrings, formatted, logLine, effectCallee, updatedSequenceNodePath, } = await (0, update_keyframes_1.updateEffectKeyframes)({
|
|
27
27
|
input: fileContents,
|
|
28
28
|
sequenceNodePath: sequenceNodePath.nodePath,
|
|
29
29
|
effectIndex,
|
|
@@ -74,7 +74,7 @@ const addEffectKeyframeHandler = ({ input: { fileName, sequenceNodePath, effectI
|
|
|
74
74
|
});
|
|
75
75
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
76
76
|
const ast = (0, parse_ast_1.parseAst)((0, node_fs_1.readFileSync)(absolutePath, 'utf-8'));
|
|
77
|
-
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast,
|
|
77
|
+
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, updatedSequenceNodePath);
|
|
78
78
|
if (!jsx) {
|
|
79
79
|
return {
|
|
80
80
|
canUpdate: false,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addEffectHandler = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const renderer_1 = require("@remotion/renderer");
|
|
6
|
+
const add_effect_1 = require("../../codemods/add-effect");
|
|
7
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
8
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
9
|
+
const format_log_file_location_1 = require("../format-log-file-location");
|
|
10
|
+
const undo_stack_1 = require("../undo-stack");
|
|
11
|
+
const formatting_1 = require("./log-updates/formatting");
|
|
12
|
+
const log_update_1 = require("./log-updates/log-update");
|
|
13
|
+
const addEffectHandler = async ({ input: { fileName, sequenceNodePath, effectName, effectImportPath, effectConfig, clientId, }, remotionRoot, logLevel, }) => {
|
|
14
|
+
try {
|
|
15
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-effect] Received request for fileName="${fileName}" effect="${effectName}"`);
|
|
16
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
17
|
+
remotionRoot,
|
|
18
|
+
fileName,
|
|
19
|
+
action: 'modify',
|
|
20
|
+
});
|
|
21
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
22
|
+
const { output, formatted, effectLabel, nodeLabel, logLine } = await (0, add_effect_1.addEffect)({
|
|
23
|
+
input: fileContents,
|
|
24
|
+
sequenceNodePath: sequenceNodePath.nodePath,
|
|
25
|
+
effectName,
|
|
26
|
+
effectImportPath,
|
|
27
|
+
effectConfig,
|
|
28
|
+
});
|
|
29
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
30
|
+
filePath: absolutePath,
|
|
31
|
+
oldContents: fileContents,
|
|
32
|
+
newContents: null,
|
|
33
|
+
logLevel,
|
|
34
|
+
remotionRoot,
|
|
35
|
+
logLine,
|
|
36
|
+
description: {
|
|
37
|
+
undoMessage: `↩️ Addition of ${effectLabel} to ${nodeLabel}`,
|
|
38
|
+
redoMessage: `↪️ Addition of ${effectLabel} to ${nodeLabel}`,
|
|
39
|
+
},
|
|
40
|
+
entryType: 'add-effect',
|
|
41
|
+
suppressHmrOnFileRestore: false,
|
|
42
|
+
});
|
|
43
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
|
|
44
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
|
|
45
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
46
|
+
remotionRoot,
|
|
47
|
+
absolutePath,
|
|
48
|
+
line: logLine,
|
|
49
|
+
});
|
|
50
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Added ${(0, formatting_1.attrName)(effectLabel)} to ${nodeLabel}`);
|
|
51
|
+
if (!formatted) {
|
|
52
|
+
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
53
|
+
}
|
|
54
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[add-effect] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
|
|
55
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
reason: err.message,
|
|
64
|
+
stack: err.stack,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
exports.addEffectHandler = addEffectHandler;
|
|
@@ -21,7 +21,7 @@ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, v
|
|
|
21
21
|
});
|
|
22
22
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
23
23
|
const parsedValue = JSON.parse(value);
|
|
24
|
-
const { output, oldValueStrings, newValueStrings, formatted, logLine } = await (0, update_keyframes_1.updateSequenceKeyframes)({
|
|
24
|
+
const { output, oldValueStrings, newValueStrings, formatted, logLine, updatedNodePath, } = await (0, update_keyframes_1.updateSequenceKeyframes)({
|
|
25
25
|
input: fileContents,
|
|
26
26
|
nodePath: nodePath.nodePath,
|
|
27
27
|
updates: [
|
|
@@ -72,13 +72,16 @@ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, v
|
|
|
72
72
|
const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
|
|
73
73
|
fileContents: output,
|
|
74
74
|
keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
|
|
75
|
-
nodePath:
|
|
75
|
+
nodePath: updatedNodePath,
|
|
76
76
|
effects: [],
|
|
77
77
|
});
|
|
78
|
+
const updatedSubscriptionKey = { ...nodePath, nodePath: updatedNodePath };
|
|
78
79
|
return {
|
|
79
80
|
canUpdate: true,
|
|
80
81
|
props: status.props,
|
|
81
|
-
results: [
|
|
82
|
+
results: [
|
|
83
|
+
{ fileName, nodePath: updatedSubscriptionKey, props: status.props },
|
|
84
|
+
],
|
|
82
85
|
};
|
|
83
86
|
});
|
|
84
87
|
exports.addSequenceKeyframeHandler = addSequenceKeyframeHandler;
|
|
@@ -5,6 +5,7 @@ export declare const isStaticValue: (node: Expression) => boolean;
|
|
|
5
5
|
export declare const extractStaticValue: (node: Expression) => unknown;
|
|
6
6
|
export declare const getComputedStatus: (node: Expression) => CanUpdateSequencePropStatus;
|
|
7
7
|
export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
|
|
8
|
+
export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
|
|
8
9
|
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
9
10
|
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, keys, effects, }: {
|
|
10
11
|
fileContents: string;
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findJsxElementAtNodePath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
|
|
36
|
+
exports.computeSequencePropsStatusFromFilenameByLine = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findNodePathForJsxElement = exports.findJsxElementAtNodePath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
38
|
const renderer_1 = require("@remotion/renderer");
|
|
39
39
|
const recast = __importStar(require("recast"));
|
|
@@ -443,6 +443,20 @@ const findJsxElementAtNodePath = (ast, nodePath) => {
|
|
|
443
443
|
return null;
|
|
444
444
|
};
|
|
445
445
|
exports.findJsxElementAtNodePath = findJsxElementAtNodePath;
|
|
446
|
+
const findNodePathForJsxElement = (ast, target) => {
|
|
447
|
+
let foundPath = null;
|
|
448
|
+
recast.types.visit(ast, {
|
|
449
|
+
visitJSXOpeningElement(p) {
|
|
450
|
+
if (p.node === target) {
|
|
451
|
+
foundPath = getNodePathForRecastPath(p);
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
return this.traverse(p);
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
return foundPath;
|
|
458
|
+
};
|
|
459
|
+
exports.findNodePathForJsxElement = findNodePathForJsxElement;
|
|
446
460
|
const lineColumnToNodePath = (ast, targetLine) => {
|
|
447
461
|
let foundPath = null;
|
|
448
462
|
recast.types.visit(ast, {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DeleteEffectKeyframe, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, SaveSequencePropsResult } from '@remotion/studio-shared';
|
|
2
|
+
import type { ApiHandler } from '../api-types';
|
|
3
|
+
export declare const deleteKeyframes: ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }: {
|
|
4
|
+
sequenceKeyframes: DeleteSequenceKeyframe[];
|
|
5
|
+
effectKeyframes: DeleteEffectKeyframe[];
|
|
6
|
+
clientId: string;
|
|
7
|
+
remotionRoot: string;
|
|
8
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
sequenceResults: SaveSequencePropsResult[];
|
|
11
|
+
effectResults: import("remotion").CanUpdateEffectPropsResponse[];
|
|
12
|
+
}>;
|
|
13
|
+
export declare const deleteKeyframesHandler: ApiHandler<DeleteKeyframesRequest, DeleteKeyframesResponse>;
|