@remotion/studio-server 4.0.528 → 4.0.530
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-composition-to-file.d.ts +7 -0
- package/dist/codemods/add-composition-to-file.js +63 -0
- package/dist/codemods/apply-codemod-to-file.js +6 -1
- package/dist/codemods/effect-param-expression.d.ts +1 -1
- package/dist/codemods/effect-param-expression.js +3 -2
- 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-local-package-override.d.ts +5 -0
- package/dist/helpers/get-local-package-override.js +39 -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/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 +40 -11
- 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-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/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/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,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;
|
|
@@ -314,7 +314,9 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
|
|
|
314
314
|
return null;
|
|
315
315
|
}
|
|
316
316
|
const extrapolateType = getExtrapolateType(value);
|
|
317
|
-
if (!extrapolateType
|
|
317
|
+
if (!extrapolateType ||
|
|
318
|
+
(interpolationFunction === 'interpolatePaths' &&
|
|
319
|
+
extrapolateType === 'identity')) {
|
|
318
320
|
return null;
|
|
319
321
|
}
|
|
320
322
|
clamping =
|
|
@@ -334,7 +336,7 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
|
|
|
334
336
|
continue;
|
|
335
337
|
}
|
|
336
338
|
if (key === 'output') {
|
|
337
|
-
if (interpolationFunction
|
|
339
|
+
if (interpolationFunction !== 'interpolate') {
|
|
338
340
|
return null;
|
|
339
341
|
}
|
|
340
342
|
const parsedOutput = getInterpolateOutputOption(value);
|
|
@@ -345,7 +347,7 @@ const getInterpolationMetadata = (interpolationFunction, callExpression, keyfram
|
|
|
345
347
|
continue;
|
|
346
348
|
}
|
|
347
349
|
if (key === 'outputType') {
|
|
348
|
-
if (interpolationFunction
|
|
350
|
+
if (interpolationFunction !== 'interpolate' ||
|
|
349
351
|
getInterpolateOutputType(value) === null) {
|
|
350
352
|
return null;
|
|
351
353
|
}
|
|
@@ -387,11 +389,16 @@ const getInterpolationKeyframes = (node, ast, videoConfigValues) => {
|
|
|
387
389
|
return undefined;
|
|
388
390
|
}
|
|
389
391
|
const callExpression = node;
|
|
390
|
-
if (callExpression.callee.type !== 'Identifier'
|
|
391
|
-
|
|
392
|
+
if (callExpression.callee.type !== 'Identifier') {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
const interpolationFunction = codemods_1.CodemodsInternals.getKeyframeInterpolationFunctionForCallee({
|
|
396
|
+
ast,
|
|
397
|
+
callee: callExpression.callee,
|
|
398
|
+
});
|
|
399
|
+
if (interpolationFunction === null) {
|
|
392
400
|
return undefined;
|
|
393
401
|
}
|
|
394
|
-
const interpolationFunction = callExpression.callee.name;
|
|
395
402
|
const frameArg = callExpression.arguments[0];
|
|
396
403
|
const inputArg = callExpression.arguments[1];
|
|
397
404
|
const outputArg = callExpression.arguments[2];
|
|
@@ -451,6 +458,7 @@ const getInterpolationKeyframes = (node, ast, videoConfigValues) => {
|
|
|
451
458
|
clamping: metadata.clamping,
|
|
452
459
|
posterize: metadata.posterize,
|
|
453
460
|
output: metadata.output,
|
|
461
|
+
keyframePlaybackRateAdjustment: frameDisplayOffset.playbackRateAdjustment,
|
|
454
462
|
keyframeDisplayOffsetAdjustment: frameDisplayOffset.hasEnclosingElement
|
|
455
463
|
? frameDisplayOffset.adjustment
|
|
456
464
|
: null,
|
|
@@ -541,6 +549,7 @@ const getFrameDisplayOffsetAdjustmentBetweenPaths = ({ startPath, endPath, video
|
|
|
541
549
|
let hasSeenControlledElement = false;
|
|
542
550
|
let hasEnclosingElement = false;
|
|
543
551
|
let adjustment = 0;
|
|
552
|
+
let playbackRateAdjustment = 1;
|
|
544
553
|
while (current && current.value !== endPath.value) {
|
|
545
554
|
const currentNode = current.value;
|
|
546
555
|
if (currentNode.type === 'FunctionDeclaration' ||
|
|
@@ -568,15 +577,30 @@ const getFrameDisplayOffsetAdjustmentBetweenPaths = ({ startPath, endPath, video
|
|
|
568
577
|
defaultValue: 0,
|
|
569
578
|
videoConfigValues,
|
|
570
579
|
});
|
|
571
|
-
|
|
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) {
|
|
572
591
|
return null;
|
|
573
592
|
}
|
|
574
|
-
|
|
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;
|
|
575
597
|
}
|
|
576
598
|
}
|
|
577
599
|
current = current.parentPath;
|
|
578
600
|
}
|
|
579
|
-
return current
|
|
601
|
+
return current
|
|
602
|
+
? { adjustment, playbackRateAdjustment, hasEnclosingElement }
|
|
603
|
+
: null;
|
|
580
604
|
};
|
|
581
605
|
const resolveCurrentFrameExpression = ({ node, ast, seenDeclarations, }) => {
|
|
582
606
|
var _a;
|
|
@@ -716,6 +740,11 @@ const getComputedStatus = (node, ast, videoConfigValues) => {
|
|
|
716
740
|
status: 'keyframed',
|
|
717
741
|
interpolationFunction: interpolation.interpolationFunction,
|
|
718
742
|
keyframeDisplayOffsetAdjustment: interpolation.keyframeDisplayOffsetAdjustment,
|
|
743
|
+
...(interpolation.keyframePlaybackRateAdjustment === 1
|
|
744
|
+
? {}
|
|
745
|
+
: {
|
|
746
|
+
keyframePlaybackRateAdjustment: interpolation.keyframePlaybackRateAdjustment,
|
|
747
|
+
}),
|
|
719
748
|
keyframes: interpolation.keyframes,
|
|
720
749
|
easing: interpolation.easing,
|
|
721
750
|
clamping: interpolation.clamping,
|
|
@@ -927,7 +956,7 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
|
|
|
927
956
|
action: 'read',
|
|
928
957
|
});
|
|
929
958
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
930
|
-
const nodes = (0, codemods_1.
|
|
959
|
+
const nodes = (0, codemods_1.getNodes)({
|
|
931
960
|
project: { rootDir: remotionRoot, files: { [absolutePath]: fileContents } },
|
|
932
961
|
filePath: absolutePath,
|
|
933
962
|
});
|
|
@@ -948,7 +977,7 @@ const resolveSequencePropsNodePathsFromFilename = ({ fileName, targets, remotion
|
|
|
948
977
|
exports.resolveSequencePropsNodePathsFromFilename = resolveSequencePropsNodePathsFromFilename;
|
|
949
978
|
const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
|
|
950
979
|
try {
|
|
951
|
-
return (0, codemods_1.
|
|
980
|
+
return (0, codemods_1.getNodeProps)({
|
|
952
981
|
project: { rootDir: '/', files: { 'source.tsx': fileContents } },
|
|
953
982
|
node: { filePath: 'source.tsx', nodePath },
|
|
954
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;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteNodesHandler = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const codemods_1 = require("@remotion/codemods");
|
|
6
|
+
const renderer_1 = require("@remotion/renderer");
|
|
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 hmr_timing_1 = require("../hmr-timing");
|
|
11
|
+
const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
|
|
12
|
+
const undo_stack_1 = require("../undo-stack");
|
|
13
|
+
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
14
|
+
const getDeletedNodeDescription = (nodeLabels) => {
|
|
15
|
+
if (nodeLabels.length === 1) {
|
|
16
|
+
return nodeLabels[0];
|
|
17
|
+
}
|
|
18
|
+
return `${nodeLabels.length} JSX nodes`;
|
|
19
|
+
};
|
|
20
|
+
const deleteNodesHandler = ({ input: { nodes }, remotionRoot, logLevel }) => {
|
|
21
|
+
return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
22
|
+
var _a;
|
|
23
|
+
try {
|
|
24
|
+
(0, hmr_timing_1.logHmrTiming)({
|
|
25
|
+
detail: null,
|
|
26
|
+
logLevel,
|
|
27
|
+
stage: 'delete-nodes-request-start',
|
|
28
|
+
});
|
|
29
|
+
if (nodes.length === 0) {
|
|
30
|
+
throw new Error('No JSX nodes were specified for deletion');
|
|
31
|
+
}
|
|
32
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-nodes] Received request to delete ${nodes.length} JSX node${nodes.length === 1 ? '' : 's'}`);
|
|
33
|
+
const itemsByFileName = new Map();
|
|
34
|
+
for (const item of nodes) {
|
|
35
|
+
const fileItems = (_a = itemsByFileName.get(item.fileName)) !== null && _a !== void 0 ? _a : [];
|
|
36
|
+
fileItems.push(item);
|
|
37
|
+
itemsByFileName.set(item.fileName, fileItems);
|
|
38
|
+
}
|
|
39
|
+
const updates = await Promise.all([...itemsByFileName.entries()].map(async ([fileName, fileItems]) => {
|
|
40
|
+
var _a;
|
|
41
|
+
var _b;
|
|
42
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
43
|
+
remotionRoot,
|
|
44
|
+
fileName,
|
|
45
|
+
action: 'modify',
|
|
46
|
+
});
|
|
47
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
48
|
+
const result = await (0, codemods_1.deleteNodes)({
|
|
49
|
+
project: {
|
|
50
|
+
files: { [absolutePath]: fileContents },
|
|
51
|
+
rootDir: remotionRoot,
|
|
52
|
+
},
|
|
53
|
+
nodes: fileItems.map((item) => ({
|
|
54
|
+
filePath: absolutePath,
|
|
55
|
+
nodePath: item.nodePath,
|
|
56
|
+
})),
|
|
57
|
+
});
|
|
58
|
+
const output = (_b = (_a = result.changes[0]) === null || _a === void 0 ? void 0 : _a.nextContents) !== null && _b !== void 0 ? _b : fileContents;
|
|
59
|
+
const { nodeLabels, logLines } = result.editDetails[0];
|
|
60
|
+
const nodePathRemappings = result.nodePathRemappings.map(({ oldNodePath, newNodePath, oldJsxName, newJsxName }) => ({
|
|
61
|
+
oldNodePath,
|
|
62
|
+
newNodePath,
|
|
63
|
+
oldJsxName,
|
|
64
|
+
newJsxName,
|
|
65
|
+
}));
|
|
66
|
+
return {
|
|
67
|
+
absolutePath,
|
|
68
|
+
fileRelativeToRoot,
|
|
69
|
+
fileContents,
|
|
70
|
+
output,
|
|
71
|
+
nodeLabels,
|
|
72
|
+
nodePathRemappings,
|
|
73
|
+
logLine: Math.min(...logLines),
|
|
74
|
+
};
|
|
75
|
+
}));
|
|
76
|
+
(0, hmr_timing_1.logHmrTiming)({
|
|
77
|
+
detail: `files=${updates.length}`,
|
|
78
|
+
logLevel,
|
|
79
|
+
stage: 'delete-nodes-codemod-complete',
|
|
80
|
+
});
|
|
81
|
+
const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(updates.map((update) => ({
|
|
82
|
+
absolutePath: update.absolutePath,
|
|
83
|
+
remappings: update.nodePathRemappings,
|
|
84
|
+
})), null);
|
|
85
|
+
for (const update of updates) {
|
|
86
|
+
const deletedNodeDescription = getDeletedNodeDescription(update.nodeLabels);
|
|
87
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
88
|
+
filePath: update.absolutePath,
|
|
89
|
+
oldContents: update.fileContents,
|
|
90
|
+
newContents: null,
|
|
91
|
+
logLevel,
|
|
92
|
+
remotionRoot,
|
|
93
|
+
logLine: update.logLine,
|
|
94
|
+
description: {
|
|
95
|
+
undoMessage: `↩️ Deletion of ${deletedNodeDescription}`,
|
|
96
|
+
redoMessage: `↪️ Deletion of ${deletedNodeDescription}`,
|
|
97
|
+
},
|
|
98
|
+
entryType: 'delete-nodes',
|
|
99
|
+
suppressHmrOnFileRestore: false,
|
|
100
|
+
nodePathRemappings: update.nodePathRemappings,
|
|
101
|
+
});
|
|
102
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(update.absolutePath);
|
|
103
|
+
(0, hmr_timing_1.logHmrTiming)({
|
|
104
|
+
detail: `file=${update.fileRelativeToRoot}`,
|
|
105
|
+
logLevel,
|
|
106
|
+
stage: 'source-file-write-start',
|
|
107
|
+
});
|
|
108
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
109
|
+
file: update.absolutePath,
|
|
110
|
+
content: update.output,
|
|
111
|
+
originatorClientId: undefined,
|
|
112
|
+
metadata: { skipSequencePropsUpdate: true },
|
|
113
|
+
});
|
|
114
|
+
(0, hmr_timing_1.logHmrTiming)({
|
|
115
|
+
detail: `file=${update.fileRelativeToRoot}`,
|
|
116
|
+
logLevel,
|
|
117
|
+
stage: 'source-file-write-complete',
|
|
118
|
+
});
|
|
119
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
120
|
+
remotionRoot,
|
|
121
|
+
absolutePath: update.absolutePath,
|
|
122
|
+
line: update.logLine,
|
|
123
|
+
});
|
|
124
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Deleted ${deletedNodeDescription}`);
|
|
125
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[delete-nodes] Wrote ${update.fileRelativeToRoot}`);
|
|
126
|
+
}
|
|
127
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
nodePathMutation,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
reason: err.message,
|
|
137
|
+
stack: err.stack,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
exports.deleteNodesHandler = deleteNodesHandler;
|