@remotion/studio-server 4.0.529 → 4.0.531
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/canvas-capture/generate-canvas-capture-composition.d.ts +14 -0
- package/dist/canvas-capture/generate-canvas-capture-composition.js +239 -0
- package/dist/codemods/add-composition-to-file.d.ts +7 -0
- package/dist/codemods/add-composition-to-file.js +63 -0
- package/dist/codemods/add-effect.d.ts +1 -0
- package/dist/codemods/add-effect.js +8 -0
- package/dist/codemods/apply-codemod-to-file.js +6 -1
- package/dist/codemods/apply-visual-control.d.ts +8 -0
- package/dist/codemods/apply-visual-control.js +89 -0
- package/dist/codemods/delete-effect.d.ts +1 -0
- package/dist/codemods/delete-effect.js +6 -0
- package/dist/codemods/delete-jsx-node.d.ts +22 -0
- package/dist/codemods/delete-jsx-node.js +17 -0
- package/dist/codemods/duplicate-composition.d.ts +2 -0
- package/dist/codemods/duplicate-composition.js +64 -0
- package/dist/codemods/duplicate-effect.d.ts +1 -0
- package/dist/codemods/duplicate-effect.js +6 -0
- package/dist/codemods/duplicate-jsx-node.d.ts +25 -0
- package/dist/codemods/duplicate-jsx-node.js +26 -0
- package/dist/codemods/format-file-content.d.ts +7 -0
- package/dist/codemods/format-file-content.js +80 -0
- package/dist/codemods/format-inline-content.d.ts +18 -0
- package/dist/codemods/format-inline-content.js +78 -0
- package/dist/codemods/insert-video-layers.d.ts +11 -0
- package/dist/codemods/insert-video-layers.js +5 -0
- package/dist/codemods/recast-mods.d.ts +13 -0
- package/dist/codemods/recast-mods.js +902 -0
- package/dist/codemods/reorder-effect.d.ts +1 -0
- package/dist/codemods/reorder-effect.js +5 -0
- package/dist/codemods/reorder-sequence.d.ts +1 -0
- package/dist/codemods/reorder-sequence.js +5 -0
- package/dist/codemods/simple-diff.d.ts +5 -0
- package/dist/codemods/simple-diff.js +39 -0
- package/dist/codemods/split-video-from-audio.d.ts +1 -0
- package/dist/codemods/split-video-from-audio.js +5 -0
- package/dist/codemods/update-default-props.d.ts +1 -0
- package/dist/codemods/update-default-props.js +6 -0
- package/dist/codemods/update-inline-caption-patches.d.ts +1 -0
- package/dist/codemods/update-inline-caption-patches.js +5 -0
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +1 -0
- package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +7 -0
- package/dist/codemods/update-keyframes/update-keyframes.d.ts +3 -3
- package/dist/codemods/update-keyframes/update-keyframes.js +1 -1
- package/dist/codemods/update-sequence-props/update-sequence-props.js +1 -1
- package/dist/helpers/get-file-source.js +6 -4
- package/dist/helpers/get-local-package-override.d.ts +5 -0
- package/dist/helpers/get-local-package-override.js +39 -0
- package/dist/helpers/install-command.js +1 -0
- package/dist/helpers/resolve-composition-component.d.ts +2 -1
- package/dist/helpers/resolve-composition-component.js +66 -15
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/open-directory-in-finder.js +11 -9
- package/dist/preview-server/api-routes.js +32 -12
- package/dist/preview-server/element-install-state.js +10 -2
- package/dist/preview-server/routes/add-composition.d.ts +3 -0
- package/dist/preview-server/routes/add-composition.js +97 -0
- package/dist/preview-server/routes/add-folder.d.ts +3 -0
- package/dist/preview-server/routes/add-folder.js +107 -0
- package/dist/preview-server/routes/add-keyframes.d.ts +2 -2
- package/dist/preview-server/routes/add-keyframes.js +49 -6
- package/dist/preview-server/routes/can-update-sequence-props.js +27 -5
- package/dist/preview-server/routes/delete-composition.d.ts +3 -0
- package/dist/preview-server/routes/delete-composition.js +104 -0
- package/dist/preview-server/routes/delete-jsx-node.d.ts +3 -0
- package/dist/preview-server/routes/delete-jsx-node.js +126 -0
- package/dist/preview-server/routes/delete-nodes.d.ts +3 -0
- package/dist/preview-server/routes/delete-nodes.js +142 -0
- package/dist/preview-server/routes/duplicate-composition.d.ts +3 -0
- package/dist/preview-server/routes/duplicate-composition.js +114 -0
- package/dist/preview-server/routes/duplicate-nodes.d.ts +3 -0
- package/dist/preview-server/routes/duplicate-nodes.js +123 -0
- package/dist/preview-server/routes/insert-basic-captions.js +2 -1
- package/dist/preview-server/routes/insert-composition-element.d.ts +3 -0
- package/dist/preview-server/routes/insert-composition-element.js +236 -0
- package/dist/preview-server/routes/insert-element.js +26 -19
- package/dist/preview-server/routes/insert-video-layers.d.ts +3 -0
- package/dist/preview-server/routes/insert-video-layers.js +68 -0
- package/dist/preview-server/routes/install-dependency.js +10 -1
- package/dist/preview-server/routes/move-composition.d.ts +3 -0
- package/dist/preview-server/routes/move-composition.js +148 -0
- package/dist/preview-server/routes/move-folder.d.ts +3 -0
- package/dist/preview-server/routes/move-folder.js +151 -0
- package/dist/preview-server/routes/precompose-jsx-nodes.d.ts +3 -0
- package/dist/preview-server/routes/precompose-jsx-nodes.js +209 -0
- package/dist/preview-server/routes/rename-composition.d.ts +3 -0
- package/dist/preview-server/routes/rename-composition.js +105 -0
- package/dist/preview-server/routes/rename-folder.d.ts +3 -0
- package/dist/preview-server/routes/rename-folder.js +111 -0
- package/dist/preview-server/routes/reorder-sequence.js +7 -2
- package/dist/preview-server/routes/replace-video-source.js +7 -2
- package/dist/preview-server/routes/save-sequence-props.js +6 -3
- package/dist/preview-server/routes/split-sequences.d.ts +3 -0
- package/dist/preview-server/routes/split-sequences.js +122 -0
- package/dist/preview-server/routes/split-video-from-audio.js +6 -1
- package/dist/preview-server/routes/unwrap-folder.d.ts +3 -0
- package/dist/preview-server/routes/unwrap-folder.js +107 -0
- package/dist/preview-server/routes/update-composition-metadata.d.ts +3 -0
- package/dist/preview-server/routes/update-composition-metadata.js +110 -0
- package/dist/preview-server/routes/update-public-license.d.ts +11 -0
- package/dist/preview-server/routes/update-public-license.js +97 -0
- package/dist/preview-server/routes/wrap-node.d.ts +3 -0
- package/dist/preview-server/routes/wrap-node.js +108 -0
- package/dist/preview-server/studio-protocol/handle-discovery.js +3 -10
- package/dist/preview-server/studio-protocol/handle-install.js +0 -3
- package/dist/preview-server/undo-stack.d.ts +1 -1
- package/dist/preview-server/undo-stack.js +6 -0
- package/dist/start-studio.js +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addCompositionHandler = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const renderer_1 = require("@remotion/renderer");
|
|
6
|
+
const add_composition_to_file_1 = require("../../codemods/add-composition-to-file");
|
|
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 project_info_1 = require("../project-info");
|
|
11
|
+
const undo_stack_1 = require("../undo-stack");
|
|
12
|
+
const can_update_default_props_1 = require("./can-update-default-props");
|
|
13
|
+
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
14
|
+
const addCompositionHandler = ({ input: request, logLevel, remotionRoot, entryPoint }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
var _c, _d;
|
|
17
|
+
try {
|
|
18
|
+
let filePath;
|
|
19
|
+
if ((_a = request.symbolicatedStack) === null || _a === void 0 ? void 0 : _a.originalFileName) {
|
|
20
|
+
filePath = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
21
|
+
remotionRoot,
|
|
22
|
+
fileName: request.symbolicatedStack.originalFileName,
|
|
23
|
+
action: 'add a composition to',
|
|
24
|
+
}).absolutePath;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const { rootFile } = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
|
|
28
|
+
if (rootFile === null) {
|
|
29
|
+
throw new Error('Cannot find the Remotion root file');
|
|
30
|
+
}
|
|
31
|
+
filePath = rootFile;
|
|
32
|
+
}
|
|
33
|
+
(0, can_update_default_props_1.checkIfTypeScriptFile)(filePath);
|
|
34
|
+
const result = await (0, add_composition_to_file_1.addCompositionToFile)({
|
|
35
|
+
filePath,
|
|
36
|
+
options: request.options,
|
|
37
|
+
remotionRoot,
|
|
38
|
+
});
|
|
39
|
+
for (const change of result.changes) {
|
|
40
|
+
const currentContents = (0, node_fs_1.existsSync)(change.filePath)
|
|
41
|
+
? (0, node_fs_1.readFileSync)(change.filePath, 'utf-8')
|
|
42
|
+
: null;
|
|
43
|
+
if (currentContents !== change.previousContents) {
|
|
44
|
+
throw new Error(`Source changed before adding composition: ${change.filePath}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (result.changes.length > 0) {
|
|
48
|
+
const logLine = (_c = (_b = request.symbolicatedStack) === null || _b === void 0 ? void 0 : _b.originalLineNumber) !== null && _c !== void 0 ? _c : 1;
|
|
49
|
+
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
50
|
+
snapshots: result.changes.map((change) => ({
|
|
51
|
+
filePath: change.filePath,
|
|
52
|
+
oldContents: change.previousContents,
|
|
53
|
+
newContents: change.nextContents,
|
|
54
|
+
logLine: change.filePath === filePath ? logLine : 1,
|
|
55
|
+
nodePathRemappings: null,
|
|
56
|
+
})),
|
|
57
|
+
logLevel,
|
|
58
|
+
remotionRoot,
|
|
59
|
+
description: {
|
|
60
|
+
undoMessage: `↩️ Creation of composition "${request.options.newId}"`,
|
|
61
|
+
redoMessage: `↪️ Creation of composition "${request.options.newId}"`,
|
|
62
|
+
},
|
|
63
|
+
entryType: 'new-composition',
|
|
64
|
+
suppressHmrOnFileRestore: false,
|
|
65
|
+
undoRedoNavigation: request.undoRedoNavigation,
|
|
66
|
+
});
|
|
67
|
+
for (const change of result.changes) {
|
|
68
|
+
if (change.nextContents === null) {
|
|
69
|
+
throw new Error('Adding a composition cannot remove source files');
|
|
70
|
+
}
|
|
71
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(change.filePath);
|
|
72
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
73
|
+
file: change.filePath,
|
|
74
|
+
content: change.nextContents,
|
|
75
|
+
originatorClientId: undefined,
|
|
76
|
+
metadata: null,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
80
|
+
remotionRoot,
|
|
81
|
+
absolutePath: filePath,
|
|
82
|
+
line: logLine,
|
|
83
|
+
});
|
|
84
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(locationLabel)} Created composition "${request.options.newId}"`);
|
|
85
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
86
|
+
}
|
|
87
|
+
return { success: true, nodePathMutation: null };
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
93
|
+
stack: error instanceof Error ? ((_d = error.stack) !== null && _d !== void 0 ? _d : '') : '',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
exports.addCompositionHandler = addCompositionHandler;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.addFolderHandler = void 0;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const codemods_1 = require("@remotion/codemods");
|
|
10
|
+
const renderer_1 = require("@remotion/renderer");
|
|
11
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
12
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
13
|
+
const format_log_file_location_1 = require("../format-log-file-location");
|
|
14
|
+
const project_info_1 = require("../project-info");
|
|
15
|
+
const undo_stack_1 = require("../undo-stack");
|
|
16
|
+
const can_update_default_props_1 = require("./can-update-default-props");
|
|
17
|
+
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
18
|
+
const addFolderHandler = ({ input: request, logLevel, remotionRoot, entryPoint }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
var _c, _d;
|
|
21
|
+
try {
|
|
22
|
+
let filePath;
|
|
23
|
+
if ((_a = request.symbolicatedStack) === null || _a === void 0 ? void 0 : _a.originalFileName) {
|
|
24
|
+
filePath = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
25
|
+
remotionRoot,
|
|
26
|
+
fileName: request.symbolicatedStack.originalFileName,
|
|
27
|
+
action: 'add a folder to',
|
|
28
|
+
}).absolutePath;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const { rootFile } = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
|
|
32
|
+
if (rootFile === null) {
|
|
33
|
+
throw new Error('Cannot find the Remotion root file');
|
|
34
|
+
}
|
|
35
|
+
filePath = rootFile;
|
|
36
|
+
}
|
|
37
|
+
(0, can_update_default_props_1.checkIfTypeScriptFile)(filePath);
|
|
38
|
+
const result = (0, codemods_1.addFolder)({
|
|
39
|
+
project: {
|
|
40
|
+
files: { [filePath]: (0, node_fs_1.readFileSync)(filePath, 'utf-8') },
|
|
41
|
+
rootDir: node_path_1.default.dirname(filePath),
|
|
42
|
+
},
|
|
43
|
+
compositionFile: filePath,
|
|
44
|
+
folder: { name: request.folderName, parentName: request.parentName },
|
|
45
|
+
});
|
|
46
|
+
for (const change of result.changes) {
|
|
47
|
+
const currentContents = (0, node_fs_1.existsSync)(change.filePath)
|
|
48
|
+
? (0, node_fs_1.readFileSync)(change.filePath, 'utf-8')
|
|
49
|
+
: null;
|
|
50
|
+
if (currentContents !== change.previousContents) {
|
|
51
|
+
throw new Error(`Source changed before adding folder: ${change.filePath}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (result.changes.length > 0) {
|
|
55
|
+
const logLine = (_c = (_b = request.symbolicatedStack) === null || _b === void 0 ? void 0 : _b.originalLineNumber) !== null && _c !== void 0 ? _c : 1;
|
|
56
|
+
const folderPath = request.parentName
|
|
57
|
+
? `${request.parentName}/${request.folderName}`
|
|
58
|
+
: request.folderName;
|
|
59
|
+
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
60
|
+
snapshots: result.changes.map((change) => ({
|
|
61
|
+
filePath: change.filePath,
|
|
62
|
+
oldContents: change.previousContents,
|
|
63
|
+
newContents: change.nextContents,
|
|
64
|
+
logLine: change.filePath === filePath ? logLine : 1,
|
|
65
|
+
nodePathRemappings: null,
|
|
66
|
+
})),
|
|
67
|
+
logLevel,
|
|
68
|
+
remotionRoot,
|
|
69
|
+
description: {
|
|
70
|
+
undoMessage: `↩️ Creation of folder "${folderPath}"`,
|
|
71
|
+
redoMessage: `↪️ Creation of folder "${folderPath}"`,
|
|
72
|
+
},
|
|
73
|
+
entryType: 'new-folder',
|
|
74
|
+
suppressHmrOnFileRestore: false,
|
|
75
|
+
undoRedoNavigation: request.undoRedoNavigation,
|
|
76
|
+
});
|
|
77
|
+
for (const change of result.changes) {
|
|
78
|
+
if (change.nextContents === null) {
|
|
79
|
+
throw new Error('Adding a folder cannot remove source files');
|
|
80
|
+
}
|
|
81
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(change.filePath);
|
|
82
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
83
|
+
file: change.filePath,
|
|
84
|
+
content: change.nextContents,
|
|
85
|
+
originatorClientId: undefined,
|
|
86
|
+
metadata: null,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
90
|
+
remotionRoot,
|
|
91
|
+
absolutePath: filePath,
|
|
92
|
+
line: logLine,
|
|
93
|
+
});
|
|
94
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(locationLabel)} Created folder "${folderPath}"`);
|
|
95
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
96
|
+
}
|
|
97
|
+
return { success: true, nodePathMutation: null };
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
103
|
+
stack: error instanceof Error ? ((_d = error.stack) !== null && _d !== void 0 ? _d : '') : '',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
exports.addFolderHandler = addFolderHandler;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { AddKeyframesRequest, AddKeyframesResponse } from '@remotion/studio-shared';
|
|
1
|
+
import type { AddKeyframesRequest, AddKeyframesResponse, SequenceNodePathMutation } from '@remotion/studio-shared';
|
|
2
2
|
import type { ApiHandler } from '../api-types';
|
|
3
3
|
export declare const addKeyframes: ({ sequenceKeyframes, effectKeyframes, clientId, remotionRoot, logLevel, }: AddKeyframesRequest & {
|
|
4
4
|
readonly remotionRoot: string;
|
|
5
5
|
readonly logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
6
|
-
}) => Promise<
|
|
6
|
+
}) => Promise<SequenceNodePathMutation | null>;
|
|
7
7
|
export declare const addKeyframesHandler: ApiHandler<AddKeyframesRequest, AddKeyframesResponse>;
|
|
@@ -3,9 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addKeyframesHandler = exports.addKeyframes = void 0;
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
5
|
const renderer_1 = require("@remotion/renderer");
|
|
6
|
+
const get_node_path_remappings_1 = require("../../codemods/get-node-path-remappings");
|
|
7
|
+
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
6
8
|
const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
|
|
7
9
|
const file_watcher_1 = require("../../file-watcher");
|
|
8
10
|
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
11
|
+
const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
|
|
9
12
|
const undo_stack_1 = require("../undo-stack");
|
|
10
13
|
const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
|
|
11
14
|
const log_effect_update_1 = require("./log-updates/log-effect-update");
|
|
@@ -86,6 +89,20 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
86
89
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
87
90
|
let output = fileContents;
|
|
88
91
|
let firstLogLine = Number.POSITIVE_INFINITY;
|
|
92
|
+
const originalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(fileContents));
|
|
93
|
+
// Keyframe codemods may wrap a concise arrow in a return statement.
|
|
94
|
+
// JSX nodes remain in order, but their node paths can all change.
|
|
95
|
+
const currentPathFor = (originalPath) => {
|
|
96
|
+
const index = originalNodes.findIndex(({ nodePath }) => JSON.stringify(nodePath) === JSON.stringify(originalPath));
|
|
97
|
+
if (index === -1) {
|
|
98
|
+
throw new Error('Could not find the original JSX node for keyframing');
|
|
99
|
+
}
|
|
100
|
+
const currentNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(output));
|
|
101
|
+
if (currentNodes.length !== originalNodes.length) {
|
|
102
|
+
throw new Error('Could not remap JSX nodes after keyframing');
|
|
103
|
+
}
|
|
104
|
+
return currentNodes[index].nodePath;
|
|
105
|
+
};
|
|
89
106
|
for (const keyframeGroup of groupBy(group.sequenceKeyframes, (keyframe) => JSON.stringify(keyframe.nodePath.nodePath))) {
|
|
90
107
|
const [firstSequenceKeyframe] = keyframeGroup;
|
|
91
108
|
if (!firstSequenceKeyframe) {
|
|
@@ -93,7 +110,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
93
110
|
}
|
|
94
111
|
const result = await (0, update_keyframes_1.updateSequenceKeyframes)({
|
|
95
112
|
input: output,
|
|
96
|
-
nodePath: firstSequenceKeyframe.nodePath.nodePath,
|
|
113
|
+
nodePath: currentPathFor(firstSequenceKeyframe.nodePath.nodePath),
|
|
97
114
|
schema: firstSequenceKeyframe.schema,
|
|
98
115
|
videoConfigValues: firstSequenceKeyframe.nodePath.videoConfigValues,
|
|
99
116
|
updates: keyframeGroup.map((keyframe) => ({
|
|
@@ -125,7 +142,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
125
142
|
}
|
|
126
143
|
const result = await (0, update_keyframes_1.updateEffectKeyframes)({
|
|
127
144
|
input: output,
|
|
128
|
-
sequenceNodePath: firstEffectKeyframe.sequenceNodePath.nodePath,
|
|
145
|
+
sequenceNodePath: currentPathFor(firstEffectKeyframe.sequenceNodePath.nodePath),
|
|
129
146
|
effectIndex: firstEffectKeyframe.effectIndex,
|
|
130
147
|
schema: firstEffectKeyframe.schema,
|
|
131
148
|
videoConfigValues: firstEffectKeyframe.sequenceNodePath.videoConfigValues,
|
|
@@ -152,21 +169,39 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
152
169
|
});
|
|
153
170
|
}
|
|
154
171
|
}
|
|
172
|
+
const finalNodes = (0, get_node_path_remappings_1.captureJsxNodePaths)((0, parse_ast_1.parseAst)(output));
|
|
173
|
+
if (finalNodes.length !== originalNodes.length) {
|
|
174
|
+
throw new Error('Could not remap JSX nodes after keyframing');
|
|
175
|
+
}
|
|
155
176
|
snapshots.push({
|
|
156
177
|
filePath: absolutePath,
|
|
157
178
|
oldContents: fileContents,
|
|
158
179
|
newContents: output,
|
|
159
180
|
logLine: Number.isFinite(firstLogLine) ? firstLogLine : 1,
|
|
181
|
+
nodePathRemappings: originalNodes.flatMap(({ nodePath }, index) => {
|
|
182
|
+
const newNodePath = finalNodes[index].nodePath;
|
|
183
|
+
return JSON.stringify(nodePath) === JSON.stringify(newNodePath)
|
|
184
|
+
? []
|
|
185
|
+
: [{ oldNodePath: nodePath, newNodePath }];
|
|
186
|
+
}),
|
|
160
187
|
});
|
|
161
188
|
}
|
|
162
189
|
const [firstKeyframe] = sequenceKeyframes.length > 0 ? sequenceKeyframes : effectKeyframes;
|
|
163
190
|
if (!firstKeyframe) {
|
|
164
191
|
throw new Error('No keyframes were specified for adding');
|
|
165
192
|
}
|
|
193
|
+
const filesWithRemappings = snapshots
|
|
194
|
+
.filter((snapshot) => snapshot.nodePathRemappings.length > 0)
|
|
195
|
+
.map((snapshot) => ({
|
|
196
|
+
absolutePath: snapshot.filePath,
|
|
197
|
+
remappings: snapshot.nodePathRemappings,
|
|
198
|
+
}));
|
|
166
199
|
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
167
200
|
snapshots: snapshots.map((snapshot) => ({
|
|
168
201
|
...snapshot,
|
|
169
|
-
nodePathRemappings:
|
|
202
|
+
nodePathRemappings: snapshot.nodePathRemappings.length
|
|
203
|
+
? snapshot.nodePathRemappings
|
|
204
|
+
: null,
|
|
170
205
|
})),
|
|
171
206
|
logLevel,
|
|
172
207
|
remotionRoot,
|
|
@@ -181,6 +216,8 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
181
216
|
suppressHmrOnFileRestore: true,
|
|
182
217
|
undoRedoNavigation: null,
|
|
183
218
|
});
|
|
219
|
+
// Visual Mode evaluates keyframes from prop statuses. Remap and refresh the
|
|
220
|
+
// subscriptions instead of remounting the composition when a hook is added.
|
|
184
221
|
for (const snapshot of snapshots) {
|
|
185
222
|
(0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
|
|
186
223
|
(0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(snapshot.filePath);
|
|
@@ -188,9 +225,14 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
188
225
|
file: snapshot.filePath,
|
|
189
226
|
content: snapshot.newContents,
|
|
190
227
|
originatorClientId: clientId,
|
|
191
|
-
metadata:
|
|
228
|
+
metadata: snapshot.nodePathRemappings.length
|
|
229
|
+
? { skipSequencePropsUpdate: true }
|
|
230
|
+
: null,
|
|
192
231
|
});
|
|
193
232
|
}
|
|
233
|
+
const nodePathMutation = filesWithRemappings.length
|
|
234
|
+
? (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(filesWithRemappings, null)
|
|
235
|
+
: null;
|
|
194
236
|
for (const log of sequenceLogs) {
|
|
195
237
|
(0, log_update_1.logUpdate)({
|
|
196
238
|
fileRelativeToRoot: log.fileRelativeToRoot,
|
|
@@ -221,17 +263,18 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
|
|
|
221
263
|
});
|
|
222
264
|
}
|
|
223
265
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
266
|
+
return nodePathMutation;
|
|
224
267
|
};
|
|
225
268
|
exports.addKeyframes = addKeyframes;
|
|
226
269
|
const addKeyframesHandler = ({ input: { sequenceKeyframes, effectKeyframes, clientId }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
227
270
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-keyframes] Received request to add ${sequenceKeyframes.length + effectKeyframes.length} keyframe(s)`);
|
|
228
|
-
await (0, exports.addKeyframes)({
|
|
271
|
+
const nodePathMutation = await (0, exports.addKeyframes)({
|
|
229
272
|
sequenceKeyframes,
|
|
230
273
|
effectKeyframes,
|
|
231
274
|
clientId,
|
|
232
275
|
remotionRoot,
|
|
233
276
|
logLevel,
|
|
234
277
|
});
|
|
235
|
-
return { success: true };
|
|
278
|
+
return { success: true, nodePathMutation };
|
|
236
279
|
});
|
|
237
280
|
exports.addKeyframesHandler = addKeyframesHandler;
|
|
@@ -458,6 +458,7 @@ const getInterpolationKeyframes = (node, ast, videoConfigValues) => {
|
|
|
458
458
|
clamping: metadata.clamping,
|
|
459
459
|
posterize: metadata.posterize,
|
|
460
460
|
output: metadata.output,
|
|
461
|
+
keyframePlaybackRateAdjustment: frameDisplayOffset.playbackRateAdjustment,
|
|
461
462
|
keyframeDisplayOffsetAdjustment: frameDisplayOffset.hasEnclosingElement
|
|
462
463
|
? frameDisplayOffset.adjustment
|
|
463
464
|
: null,
|
|
@@ -548,6 +549,7 @@ const getFrameDisplayOffsetAdjustmentBetweenPaths = ({ startPath, endPath, video
|
|
|
548
549
|
let hasSeenControlledElement = false;
|
|
549
550
|
let hasEnclosingElement = false;
|
|
550
551
|
let adjustment = 0;
|
|
552
|
+
let playbackRateAdjustment = 1;
|
|
551
553
|
while (current && current.value !== endPath.value) {
|
|
552
554
|
const currentNode = current.value;
|
|
553
555
|
if (currentNode.type === 'FunctionDeclaration' ||
|
|
@@ -575,15 +577,30 @@ const getFrameDisplayOffsetAdjustmentBetweenPaths = ({ startPath, endPath, video
|
|
|
575
577
|
defaultValue: 0,
|
|
576
578
|
videoConfigValues,
|
|
577
579
|
});
|
|
578
|
-
|
|
580
|
+
const playbackRate = getJsxNumericAttribute({
|
|
581
|
+
openingElement: currentNode.openingElement,
|
|
582
|
+
name: 'playbackRate',
|
|
583
|
+
defaultValue: 1,
|
|
584
|
+
videoConfigValues,
|
|
585
|
+
});
|
|
586
|
+
if (from === null ||
|
|
587
|
+
trimBefore === null ||
|
|
588
|
+
playbackRate === null ||
|
|
589
|
+
!Number.isFinite(playbackRate) ||
|
|
590
|
+
playbackRate <= 0) {
|
|
579
591
|
return null;
|
|
580
592
|
}
|
|
581
|
-
|
|
593
|
+
// Walk from the controlled element back to the hook's scope.
|
|
594
|
+
// A sequence maps parent time to (parent - from) * rate + trimBefore.
|
|
595
|
+
adjustment = (adjustment + trimBefore) / playbackRate - from;
|
|
596
|
+
playbackRateAdjustment /= playbackRate;
|
|
582
597
|
}
|
|
583
598
|
}
|
|
584
599
|
current = current.parentPath;
|
|
585
600
|
}
|
|
586
|
-
return current
|
|
601
|
+
return current
|
|
602
|
+
? { adjustment, playbackRateAdjustment, hasEnclosingElement }
|
|
603
|
+
: null;
|
|
587
604
|
};
|
|
588
605
|
const resolveCurrentFrameExpression = ({ node, ast, seenDeclarations, }) => {
|
|
589
606
|
var _a;
|
|
@@ -723,6 +740,11 @@ const getComputedStatus = (node, ast, videoConfigValues) => {
|
|
|
723
740
|
status: 'keyframed',
|
|
724
741
|
interpolationFunction: interpolation.interpolationFunction,
|
|
725
742
|
keyframeDisplayOffsetAdjustment: interpolation.keyframeDisplayOffsetAdjustment,
|
|
743
|
+
...(interpolation.keyframePlaybackRateAdjustment === 1
|
|
744
|
+
? {}
|
|
745
|
+
: {
|
|
746
|
+
keyframePlaybackRateAdjustment: interpolation.keyframePlaybackRateAdjustment,
|
|
747
|
+
}),
|
|
726
748
|
keyframes: interpolation.keyframes,
|
|
727
749
|
easing: interpolation.easing,
|
|
728
750
|
clamping: interpolation.clamping,
|
|
@@ -934,7 +956,7 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
|
|
|
934
956
|
action: 'read',
|
|
935
957
|
});
|
|
936
958
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
937
|
-
const nodes = (0, codemods_1.
|
|
959
|
+
const nodes = (0, codemods_1.getNodes)({
|
|
938
960
|
project: { rootDir: remotionRoot, files: { [absolutePath]: fileContents } },
|
|
939
961
|
filePath: absolutePath,
|
|
940
962
|
});
|
|
@@ -955,7 +977,7 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
|
|
|
955
977
|
exports.resolveSequencePropsNodePathsFromFilename = resolveSequencePropsNodePathsFromFilename;
|
|
956
978
|
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
|
|
957
979
|
try {
|
|
958
|
-
return (0, codemods_1.
|
|
980
|
+
return (0, codemods_1.getNodeProps)({
|
|
959
981
|
project: { rootDir: '/', files: { 'source.tsx': fileContents } },
|
|
960
982
|
node: { filePath: 'source.tsx', nodePath },
|
|
961
983
|
componentIdentity,
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deleteCompositionHandler = void 0;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const codemods_1 = require("@remotion/codemods");
|
|
10
|
+
const renderer_1 = require("@remotion/renderer");
|
|
11
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
12
|
+
const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
|
|
13
|
+
const format_log_file_location_1 = require("../format-log-file-location");
|
|
14
|
+
const project_info_1 = require("../project-info");
|
|
15
|
+
const undo_stack_1 = require("../undo-stack");
|
|
16
|
+
const can_update_default_props_1 = require("./can-update-default-props");
|
|
17
|
+
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
18
|
+
const deleteCompositionHandler = ({ input: request, logLevel, remotionRoot, entryPoint }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
var _c, _d;
|
|
21
|
+
try {
|
|
22
|
+
let filePath;
|
|
23
|
+
if ((_a = request.symbolicatedStack) === null || _a === void 0 ? void 0 : _a.originalFileName) {
|
|
24
|
+
filePath = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
25
|
+
remotionRoot,
|
|
26
|
+
fileName: request.symbolicatedStack.originalFileName,
|
|
27
|
+
action: 'delete a composition from',
|
|
28
|
+
}).absolutePath;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const { rootFile } = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
|
|
32
|
+
if (rootFile === null) {
|
|
33
|
+
throw new Error('Cannot find the Remotion root file');
|
|
34
|
+
}
|
|
35
|
+
filePath = rootFile;
|
|
36
|
+
}
|
|
37
|
+
(0, can_update_default_props_1.checkIfTypeScriptFile)(filePath);
|
|
38
|
+
const result = (0, codemods_1.deleteComposition)({
|
|
39
|
+
project: {
|
|
40
|
+
files: { [filePath]: (0, node_fs_1.readFileSync)(filePath, 'utf-8') },
|
|
41
|
+
rootDir: node_path_1.default.dirname(filePath),
|
|
42
|
+
},
|
|
43
|
+
compositionFile: filePath,
|
|
44
|
+
compositionId: request.idToDelete,
|
|
45
|
+
});
|
|
46
|
+
for (const change of result.changes) {
|
|
47
|
+
const currentContents = (0, node_fs_1.existsSync)(change.filePath)
|
|
48
|
+
? (0, node_fs_1.readFileSync)(change.filePath, 'utf-8')
|
|
49
|
+
: null;
|
|
50
|
+
if (currentContents !== change.previousContents) {
|
|
51
|
+
throw new Error(`Source changed before deleting composition: ${change.filePath}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (result.changes.length > 0) {
|
|
55
|
+
const logLine = (_c = (_b = request.symbolicatedStack) === null || _b === void 0 ? void 0 : _b.originalLineNumber) !== null && _c !== void 0 ? _c : 1;
|
|
56
|
+
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
57
|
+
snapshots: result.changes.map((change) => ({
|
|
58
|
+
filePath: change.filePath,
|
|
59
|
+
oldContents: change.previousContents,
|
|
60
|
+
newContents: change.nextContents,
|
|
61
|
+
logLine: change.filePath === filePath ? logLine : 1,
|
|
62
|
+
nodePathRemappings: null,
|
|
63
|
+
})),
|
|
64
|
+
logLevel,
|
|
65
|
+
remotionRoot,
|
|
66
|
+
description: {
|
|
67
|
+
undoMessage: `↩️ Deletion of composition "${request.idToDelete}"`,
|
|
68
|
+
redoMessage: `↪️ Deletion of composition "${request.idToDelete}"`,
|
|
69
|
+
},
|
|
70
|
+
entryType: 'delete-composition',
|
|
71
|
+
suppressHmrOnFileRestore: false,
|
|
72
|
+
undoRedoNavigation: request.undoRedoNavigation,
|
|
73
|
+
});
|
|
74
|
+
for (const change of result.changes) {
|
|
75
|
+
if (change.nextContents === null) {
|
|
76
|
+
throw new Error('Deleting a composition cannot remove source files');
|
|
77
|
+
}
|
|
78
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(change.filePath);
|
|
79
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
80
|
+
file: change.filePath,
|
|
81
|
+
content: change.nextContents,
|
|
82
|
+
originatorClientId: undefined,
|
|
83
|
+
metadata: null,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
87
|
+
remotionRoot,
|
|
88
|
+
absolutePath: filePath,
|
|
89
|
+
line: logLine,
|
|
90
|
+
});
|
|
91
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(locationLabel)} Deleted composition "${request.idToDelete}"`);
|
|
92
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
93
|
+
}
|
|
94
|
+
return { success: true, nodePathMutation: null };
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
100
|
+
stack: error instanceof Error ? ((_d = error.stack) !== null && _d !== void 0 ? _d : '') : '',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
exports.deleteCompositionHandler = deleteCompositionHandler;
|