@remotion/studio-server 4.0.508 → 4.0.510
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 +174 -0
- package/dist/codemods/delete-jsx-node.js +1 -1
- package/dist/codemods/duplicate-composition.js +8 -6
- package/dist/codemods/duplicate-jsx-node.js +1 -1
- package/dist/codemods/get-node-path-remappings.d.ts +4 -1
- package/dist/codemods/get-node-path-remappings.js +2 -1
- package/dist/codemods/recast-mods.js +13 -0
- package/dist/codemods/reorder-sequence.js +1 -1
- package/dist/codemods/split-jsx-sequence.d.ts +3 -4
- package/dist/codemods/split-jsx-sequence.js +6 -60
- package/dist/codemods/update-keyframes/update-keyframes.js +17 -10
- package/dist/helpers/git-client-registry.d.ts +30 -0
- package/dist/helpers/git-client-registry.js +130 -0
- package/dist/helpers/github-desktop-artwork.d.ts +1 -0
- package/dist/helpers/github-desktop-artwork.js +6 -0
- package/dist/helpers/resolve-composition-component.d.ts +2 -0
- package/dist/helpers/resolve-composition-component.js +4 -2
- package/dist/index.d.ts +2 -1
- package/dist/preview-server/api-routes.js +2 -0
- package/dist/preview-server/routes/app-icon.js +12 -7
- package/dist/preview-server/routes/apply-codemod.js +19 -3
- package/dist/preview-server/routes/default-coding-agent.js +3 -0
- package/dist/preview-server/routes/insert-jsx-element.js +7 -1
- package/dist/preview-server/routes/open-in-git-client.d.ts +3 -0
- package/dist/preview-server/routes/open-in-git-client.js +13 -0
- package/dist/preview-server/routes/save-sequence-props.js +19 -3
- package/dist/preview-server/routes/split-jsx-sequence.js +7 -2
- package/dist/preview-server/start-server.d.ts +1 -0
- package/dist/preview-server/start-server.js +1 -0
- package/dist/routes.d.ts +2 -1
- package/dist/routes.js +4 -2
- package/dist/start-studio.d.ts +2 -1
- package/dist/start-studio.js +2 -1
- package/package.json +8 -8
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CanvasCaptureData } from '@remotion/studio-shared';
|
|
2
|
+
export declare const generateCanvasCaptureComposition: ({ componentName, compositionId, data, durationInFrames, fps, height, keyframeFps, videoFileName, videoHeight, videoWidth, width, }: {
|
|
3
|
+
readonly componentName: string;
|
|
4
|
+
readonly compositionId: string;
|
|
5
|
+
readonly data: CanvasCaptureData;
|
|
6
|
+
readonly durationInFrames: number;
|
|
7
|
+
readonly fps: number;
|
|
8
|
+
readonly height: number;
|
|
9
|
+
readonly keyframeFps: number;
|
|
10
|
+
readonly videoFileName: string;
|
|
11
|
+
readonly videoHeight: number;
|
|
12
|
+
readonly videoWidth: number;
|
|
13
|
+
readonly width: number;
|
|
14
|
+
}) => Promise<string>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCanvasCaptureComposition = void 0;
|
|
4
|
+
const duplicate_composition_1 = require("../codemods/duplicate-composition");
|
|
5
|
+
const customCursorRegex = /^\s*url\(/;
|
|
6
|
+
const collapseMouseMovementsByFrame = ({ data, keyframeFps, }) => {
|
|
7
|
+
const movements = [];
|
|
8
|
+
for (const movement of data.mouseMovements) {
|
|
9
|
+
if (movement.canvasX === null || movement.canvasY === null) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const framedMovement = {
|
|
13
|
+
...movement,
|
|
14
|
+
frame: Math.ceil(movement.timeInSeconds * keyframeFps),
|
|
15
|
+
};
|
|
16
|
+
const previous = movements.at(-1);
|
|
17
|
+
if ((previous === null || previous === void 0 ? void 0 : previous.frame) === framedMovement.frame) {
|
|
18
|
+
movements[movements.length - 1] = framedMovement;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
movements.push(framedMovement);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return movements;
|
|
25
|
+
};
|
|
26
|
+
const getCursorName = (cursor) => {
|
|
27
|
+
var _a;
|
|
28
|
+
if (customCursorRegex.test(cursor)) {
|
|
29
|
+
return 'custom';
|
|
30
|
+
}
|
|
31
|
+
return ((_a = cursor.split(',').at(-1)) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase()) || 'default';
|
|
32
|
+
};
|
|
33
|
+
const serialize = (value) => JSON.stringify(value);
|
|
34
|
+
const generateCanvasCaptureComposition = ({ componentName, compositionId, data, durationInFrames, fps, height, keyframeFps, videoFileName, videoHeight, videoWidth, width, }) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const movements = collapseMouseMovementsByFrame({ data, keyframeFps });
|
|
37
|
+
if (movements.length === 0) {
|
|
38
|
+
throw new Error('The Canvas Capture does not contain cursor movements');
|
|
39
|
+
}
|
|
40
|
+
const cursorKeyframes = movements.reduce((keyframes, movement) => {
|
|
41
|
+
var _a;
|
|
42
|
+
const value = getCursorName(movement.cursor);
|
|
43
|
+
if (((_a = keyframes.at(-1)) === null || _a === void 0 ? void 0 : _a.value) !== value) {
|
|
44
|
+
keyframes.push({ frame: movement.frame, value });
|
|
45
|
+
}
|
|
46
|
+
return keyframes;
|
|
47
|
+
}, []);
|
|
48
|
+
const positionKeyframes = [];
|
|
49
|
+
for (const movement of movements) {
|
|
50
|
+
const previous = positionKeyframes.at(-1);
|
|
51
|
+
if (previous !== undefined && movement.frame - previous.frame > 1) {
|
|
52
|
+
positionKeyframes.push({
|
|
53
|
+
frame: movement.frame - 1,
|
|
54
|
+
value: previous.value,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
positionKeyframes.push({
|
|
58
|
+
frame: movement.frame,
|
|
59
|
+
value: `${movement.canvasX}px ${movement.canvasY}px`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const scaleKeyframes = [
|
|
63
|
+
{ frame: 0, value: data.captureMetadata.density },
|
|
64
|
+
...data.pointerClicks.map((click) => ({
|
|
65
|
+
frame: Math.ceil(click.timeInSeconds * keyframeFps),
|
|
66
|
+
value: click.type === 'pointer-down'
|
|
67
|
+
? data.captureMetadata.density * 0.9
|
|
68
|
+
: data.captureMetadata.density,
|
|
69
|
+
})),
|
|
70
|
+
].reduce((keyframes, keyframe) => {
|
|
71
|
+
var _a, _b;
|
|
72
|
+
if (((_a = keyframes.at(-1)) === null || _a === void 0 ? void 0 : _a.frame) === keyframe.frame) {
|
|
73
|
+
keyframes[keyframes.length - 1] = keyframe;
|
|
74
|
+
}
|
|
75
|
+
else if (((_b = keyframes.at(-1)) === null || _b === void 0 ? void 0 : _b.value) !== keyframe.value) {
|
|
76
|
+
keyframes.push(keyframe);
|
|
77
|
+
}
|
|
78
|
+
return keyframes;
|
|
79
|
+
}, []);
|
|
80
|
+
const customCursor = (_a = movements.find((movement) => customCursorRegex.test(movement.cursor))) === null || _a === void 0 ? void 0 : _a.cursor;
|
|
81
|
+
const cursorProp = cursorKeyframes.length === 1
|
|
82
|
+
? `cursor=${serialize(cursorKeyframes[0].value)}`
|
|
83
|
+
: `cursor={interpolate(
|
|
84
|
+
frame,
|
|
85
|
+
${serialize(cursorKeyframes.map((keyframe) => keyframe.frame))},
|
|
86
|
+
${serialize(cursorKeyframes.map((keyframe) => keyframe.value))},
|
|
87
|
+
{
|
|
88
|
+
easing: Easing.step1,
|
|
89
|
+
extrapolateLeft: 'clamp',
|
|
90
|
+
extrapolateRight: 'clamp',
|
|
91
|
+
},
|
|
92
|
+
)}`;
|
|
93
|
+
const scale = scaleKeyframes.length === 1
|
|
94
|
+
? serialize(scaleKeyframes[0].value)
|
|
95
|
+
: `interpolate(
|
|
96
|
+
frame,
|
|
97
|
+
${serialize(scaleKeyframes.map((keyframe) => keyframe.frame))},
|
|
98
|
+
${serialize(scaleKeyframes.map((keyframe) => keyframe.value))},
|
|
99
|
+
{
|
|
100
|
+
easing: Easing.step1,
|
|
101
|
+
extrapolateLeft: 'clamp',
|
|
102
|
+
extrapolateRight: 'clamp',
|
|
103
|
+
},
|
|
104
|
+
)`;
|
|
105
|
+
const translate = positionKeyframes.length === 1
|
|
106
|
+
? serialize(positionKeyframes[0].value)
|
|
107
|
+
: `interpolate(
|
|
108
|
+
frame,
|
|
109
|
+
${serialize(positionKeyframes.map((keyframe) => keyframe.frame))},
|
|
110
|
+
${serialize(positionKeyframes.map((keyframe) => keyframe.value))},
|
|
111
|
+
{
|
|
112
|
+
extrapolateLeft: 'clamp',
|
|
113
|
+
extrapolateRight: 'clamp',
|
|
114
|
+
},
|
|
115
|
+
)`;
|
|
116
|
+
const previewComponentName = componentName.endsWith('Composition')
|
|
117
|
+
? `${componentName.slice(0, -'Composition'.length)}Preview`
|
|
118
|
+
: `${componentName}Preview`;
|
|
119
|
+
return (0, duplicate_composition_1.formatOutput)(`import {MacOSCursor} from '@remotion/mac-cursors';
|
|
120
|
+
import {Video} from '@remotion/media';
|
|
121
|
+
import {
|
|
122
|
+
AbsoluteFill,
|
|
123
|
+
Composition,
|
|
124
|
+
Easing,
|
|
125
|
+
interpolate,
|
|
126
|
+
staticFile,
|
|
127
|
+
useCurrentFrame,
|
|
128
|
+
} from 'remotion';
|
|
129
|
+
|
|
130
|
+
export const ${previewComponentName} = () => {
|
|
131
|
+
const frame = useCurrentFrame();
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<AbsoluteFill
|
|
135
|
+
style={{
|
|
136
|
+
width: ${videoWidth},
|
|
137
|
+
height: ${videoHeight},
|
|
138
|
+
}}
|
|
139
|
+
>
|
|
140
|
+
<Video
|
|
141
|
+
src={staticFile(${serialize(videoFileName)})}
|
|
142
|
+
style={{
|
|
143
|
+
position: 'absolute',
|
|
144
|
+
}}
|
|
145
|
+
/>
|
|
146
|
+
<MacOSCursor
|
|
147
|
+
${cursorProp}
|
|
148
|
+
${customCursor === undefined ? '' : `\t\t\t\tcustomCursor={${serialize(customCursor)}}\n`} style={{
|
|
149
|
+
position: 'absolute',
|
|
150
|
+
left: 0,
|
|
151
|
+
top: 0,
|
|
152
|
+
scale: ${scale},
|
|
153
|
+
translate: ${translate},
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
</AbsoluteFill>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const ${componentName} = () => {
|
|
161
|
+
return (
|
|
162
|
+
<Composition
|
|
163
|
+
id=${serialize(compositionId)}
|
|
164
|
+
component={${previewComponentName}}
|
|
165
|
+
width={${width}}
|
|
166
|
+
height={${height}}
|
|
167
|
+
fps={${fps}}
|
|
168
|
+
durationInFrames={${durationInFrames}}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
`);
|
|
173
|
+
};
|
|
174
|
+
exports.generateCanvasCaptureComposition = generateCanvasCaptureComposition;
|
|
@@ -316,7 +316,7 @@ const deleteJsxNodes = async ({ input, nodePaths, prettierConfigOverride, }) =>
|
|
|
316
316
|
input: finalFile,
|
|
317
317
|
prettierConfigOverride,
|
|
318
318
|
});
|
|
319
|
-
const nodePathRemappings = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
319
|
+
const { nodePathRemappings } = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
320
320
|
ast,
|
|
321
321
|
captured: capturedNodePaths,
|
|
322
322
|
output,
|
|
@@ -81,12 +81,14 @@ const parseAndApplyCodemod = ({ input, codeMod, }) => {
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
if (codeMod.type === 'new-composition') {
|
|
84
|
-
(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
if (codeMod.canvasCapture === null) {
|
|
85
|
+
(0, imports_1.ensureNamedImport)({
|
|
86
|
+
ast: newAst,
|
|
87
|
+
importedName: 'Composition',
|
|
88
|
+
sourcePath: 'remotion',
|
|
89
|
+
localName: 'Composition',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
90
92
|
(0, imports_1.ensureNamedImport)({
|
|
91
93
|
ast: newAst,
|
|
92
94
|
importedName: codeMod.componentName,
|
|
@@ -303,7 +303,7 @@ const duplicateJsxNode = async ({ input, nodePath, prettierConfigOverride, }) =>
|
|
|
303
303
|
input: finalFile,
|
|
304
304
|
prettierConfigOverride,
|
|
305
305
|
});
|
|
306
|
-
const nodePathRemappings = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
306
|
+
const { nodePathRemappings } = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
307
307
|
ast,
|
|
308
308
|
captured: capturedNodePaths,
|
|
309
309
|
output,
|
|
@@ -10,4 +10,7 @@ export declare const getNodePathRemappings: ({ ast, captured, output, }: {
|
|
|
10
10
|
ast: File;
|
|
11
11
|
captured: CapturedJsxNodePath[];
|
|
12
12
|
output: string;
|
|
13
|
-
}) =>
|
|
13
|
+
}) => {
|
|
14
|
+
nodePathRemappings: SequenceNodePathRemapping[];
|
|
15
|
+
finalNodePathByNode: Map<JSXOpeningElement, SequenceNodePath>;
|
|
16
|
+
};
|
|
@@ -74,7 +74,7 @@ const getNodePathRemappings = ({ ast, captured, output, }) => {
|
|
|
74
74
|
for (let i = 0; i < nodesAfterMutation.length; i++) {
|
|
75
75
|
finalNodePathByNode.set(nodesAfterMutation[i], finalNodePaths[i]);
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
const nodePathRemappings = captured.flatMap(({ node, nodePath }) => {
|
|
78
78
|
var _a;
|
|
79
79
|
const newNodePath = (_a = finalNodePathByNode.get(node)) !== null && _a !== void 0 ? _a : null;
|
|
80
80
|
if (newNodePath !== null &&
|
|
@@ -83,5 +83,6 @@ const getNodePathRemappings = ({ ast, captured, output, }) => {
|
|
|
83
83
|
}
|
|
84
84
|
return [{ oldNodePath: nodePath, newNodePath }];
|
|
85
85
|
});
|
|
86
|
+
return { finalNodePathByNode, nodePathRemappings };
|
|
86
87
|
};
|
|
87
88
|
exports.getNodePathRemappings = getNodePathRemappings;
|
|
@@ -164,6 +164,19 @@ const jsxAttributeWithExpression = (name, expression) => ({
|
|
|
164
164
|
},
|
|
165
165
|
});
|
|
166
166
|
const newCompositionElement = (transformation) => {
|
|
167
|
+
if (transformation.canvasCapture !== null) {
|
|
168
|
+
return {
|
|
169
|
+
type: 'JSXElement',
|
|
170
|
+
openingElement: {
|
|
171
|
+
type: 'JSXOpeningElement',
|
|
172
|
+
name: jsxId(transformation.componentName),
|
|
173
|
+
attributes: [],
|
|
174
|
+
selfClosing: true,
|
|
175
|
+
},
|
|
176
|
+
closingElement: null,
|
|
177
|
+
children: [],
|
|
178
|
+
};
|
|
179
|
+
}
|
|
167
180
|
return {
|
|
168
181
|
type: 'JSXElement',
|
|
169
182
|
openingElement: {
|
|
@@ -101,7 +101,7 @@ const reorderSequence = async ({ input, sourceNodePath, targetNodePath, position
|
|
|
101
101
|
input: finalFile,
|
|
102
102
|
prettierConfigOverride,
|
|
103
103
|
});
|
|
104
|
-
const nodePathRemappings = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
104
|
+
const { nodePathRemappings } = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
105
105
|
ast,
|
|
106
106
|
captured: capturedNodePaths,
|
|
107
107
|
output,
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SequenceNodePathRemapping } from '@remotion/studio-shared';
|
|
2
2
|
import type { SequenceNodePath } from 'remotion';
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const getIsSplittableSequenceTag: (tagName: string) => boolean;
|
|
5
|
-
export declare const splitJsxSequence: ({ input, nodePath, splitFrame, prettierConfigOverride, }: {
|
|
3
|
+
export declare const splitJsxSequence: ({ input, nodePath, sequenceKeys, splitFrame, prettierConfigOverride, }: {
|
|
6
4
|
input: string;
|
|
7
5
|
nodePath: SequenceNodePath;
|
|
6
|
+
sequenceKeys: string[];
|
|
8
7
|
splitFrame: number;
|
|
9
8
|
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
10
9
|
}) => Promise<{
|
|
@@ -33,8 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.splitJsxSequence =
|
|
36
|
+
exports.splitJsxSequence = void 0;
|
|
37
37
|
const types_1 = require("@babel/types");
|
|
38
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
38
39
|
const recast = __importStar(require("recast"));
|
|
39
40
|
const delete_jsx_node_1 = require("./delete-jsx-node");
|
|
40
41
|
const format_file_content_1 = require("./format-file-content");
|
|
@@ -172,38 +173,6 @@ const orderTimingAttributes = (element) => {
|
|
|
172
173
|
const insertionIndex = Math.min(firstTimingIndex, otherAttributes.length);
|
|
173
174
|
attributes.splice(0, attributes.length, ...otherAttributes.slice(0, insertionIndex), ...orderedTimingAttributes, ...otherAttributes.slice(insertionIndex));
|
|
174
175
|
};
|
|
175
|
-
const splittableSequenceTags = new Set([
|
|
176
|
-
'AnimatedImage',
|
|
177
|
-
'Arrow',
|
|
178
|
-
'Audio',
|
|
179
|
-
'Callout',
|
|
180
|
-
'CanvasImage',
|
|
181
|
-
'Circle',
|
|
182
|
-
'Ellipse',
|
|
183
|
-
'Gif',
|
|
184
|
-
'Heart',
|
|
185
|
-
'Html5Audio',
|
|
186
|
-
'Html5Video',
|
|
187
|
-
'HtmlInCanvas',
|
|
188
|
-
'Img',
|
|
189
|
-
'OffthreadVideo',
|
|
190
|
-
'Pie',
|
|
191
|
-
'Polygon',
|
|
192
|
-
'Rect',
|
|
193
|
-
'RemotionRiveCanvas',
|
|
194
|
-
'Sequence',
|
|
195
|
-
'Solid',
|
|
196
|
-
'Spark',
|
|
197
|
-
'Star',
|
|
198
|
-
'Starburst',
|
|
199
|
-
'Triangle',
|
|
200
|
-
'Video',
|
|
201
|
-
]);
|
|
202
|
-
const unsupportedSequenceTags = new Set([
|
|
203
|
-
'Series.Sequence',
|
|
204
|
-
'TransitionSeries.Overlay',
|
|
205
|
-
'TransitionSeries.Sequence',
|
|
206
|
-
]);
|
|
207
176
|
const jsxMemberNameToString = (name) => {
|
|
208
177
|
if (name.type === 'JSXIdentifier') {
|
|
209
178
|
return name.name;
|
|
@@ -216,25 +185,6 @@ const jsxNameToString = (name) => {
|
|
|
216
185
|
}
|
|
217
186
|
return jsxMemberNameToString(name);
|
|
218
187
|
};
|
|
219
|
-
const getSplitUnsupportedSequenceTagReason = (tagName) => {
|
|
220
|
-
if (tagName === 'Series.Sequence' ||
|
|
221
|
-
tagName === 'TransitionSeries.Sequence' ||
|
|
222
|
-
tagName === 'TransitionSeries.Overlay') {
|
|
223
|
-
return `<${tagName}> cannot be split from source`;
|
|
224
|
-
}
|
|
225
|
-
return null;
|
|
226
|
-
};
|
|
227
|
-
exports.getSplitUnsupportedSequenceTagReason = getSplitUnsupportedSequenceTagReason;
|
|
228
|
-
const getIsSplittableSequenceTag = (tagName) => {
|
|
229
|
-
if (unsupportedSequenceTags.has(tagName)) {
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
if (tagName.startsWith('Interactive.')) {
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
return splittableSequenceTags.has(tagName);
|
|
236
|
-
};
|
|
237
|
-
exports.getIsSplittableSequenceTag = getIsSplittableSequenceTag;
|
|
238
188
|
const getSplittableSequenceTagName = (element) => {
|
|
239
189
|
return jsxNameToString(element.openingElement.name);
|
|
240
190
|
};
|
|
@@ -269,7 +219,7 @@ const insertAfter = (parentNode, node, clone) => {
|
|
|
269
219
|
}
|
|
270
220
|
return false;
|
|
271
221
|
};
|
|
272
|
-
const splitJsxSequence = async ({ input, nodePath, splitFrame, prettierConfigOverride, }) => {
|
|
222
|
+
const splitJsxSequence = async ({ input, nodePath, sequenceKeys, splitFrame, prettierConfigOverride, }) => {
|
|
273
223
|
var _a, _b;
|
|
274
224
|
var _c, _d;
|
|
275
225
|
if (!Number.isInteger(splitFrame)) {
|
|
@@ -283,12 +233,8 @@ const splitJsxSequence = async ({ input, nodePath, splitFrame, prettierConfigOve
|
|
|
283
233
|
}
|
|
284
234
|
const jsxElement = jsxPath.node;
|
|
285
235
|
const tagName = getSplittableSequenceTagName(jsxElement);
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
throw new Error(unsupportedReason);
|
|
289
|
-
}
|
|
290
|
-
if (!(0, exports.getIsSplittableSequenceTag)(tagName)) {
|
|
291
|
-
throw new Error(`<${tagName}> does not support sequence timing props and cannot be split`);
|
|
236
|
+
if (!(0, studio_shared_1.hasSequenceTimingTraits)(sequenceKeys)) {
|
|
237
|
+
throw new Error(`<${tagName}> cannot be split`);
|
|
292
238
|
}
|
|
293
239
|
const timing = readSequenceTiming(jsxElement);
|
|
294
240
|
const finiteEnd = timing.durationInFrames === Infinity
|
|
@@ -342,7 +288,7 @@ const splitJsxSequence = async ({ input, nodePath, splitFrame, prettierConfigOve
|
|
|
342
288
|
input: finalFile,
|
|
343
289
|
prettierConfigOverride,
|
|
344
290
|
});
|
|
345
|
-
const nodePathRemappings = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
291
|
+
const { nodePathRemappings } = (0, get_node_path_remappings_1.getNodePathRemappings)({
|
|
346
292
|
ast,
|
|
347
293
|
captured: capturedNodePaths,
|
|
348
294
|
output,
|
|
@@ -334,18 +334,16 @@ const getInlineOptionsFromExtraArgs = (extraArgs) => {
|
|
|
334
334
|
}
|
|
335
335
|
return existingOptions;
|
|
336
336
|
};
|
|
337
|
-
const normalizeEasingAfterAddingKeyframe = ({ extraArgs, previousSegmentCount, nextSegmentCount, insertedKeyframeIndex, nextKeyframeCount, }) => {
|
|
338
|
-
|
|
337
|
+
const normalizeEasingAfterAddingKeyframe = ({ extraArgs, previousSegmentCount, nextSegmentCount, insertedKeyframeIndex, nextKeyframeCount, defaultEasing, }) => {
|
|
338
|
+
var _a, _b;
|
|
339
|
+
const options = (_a = getInlineOptionsFromExtraArgs(extraArgs)) !== null && _a !== void 0 ? _a : (extraArgs.length === 0 ? createEmptyOptionsExpression() : null);
|
|
339
340
|
if (!options) {
|
|
340
341
|
return { extraArgs, needsEasingImport: false };
|
|
341
342
|
}
|
|
342
|
-
const easing = getExistingEasingArrayOrNull({
|
|
343
|
+
const easing = (_b = getExistingEasingArrayOrNull({
|
|
343
344
|
options,
|
|
344
345
|
segmentCount: previousSegmentCount,
|
|
345
|
-
});
|
|
346
|
-
if (easing === null) {
|
|
347
|
-
return { extraArgs, needsEasingImport: false };
|
|
348
|
-
}
|
|
346
|
+
})) !== null && _b !== void 0 ? _b : Array.from({ length: previousSegmentCount }, () => defaultEasing);
|
|
349
347
|
if (easing.length < nextSegmentCount) {
|
|
350
348
|
const isSplittingExistingSegment = insertedKeyframeIndex > 0 &&
|
|
351
349
|
insertedKeyframeIndex < nextKeyframeCount - 1;
|
|
@@ -353,15 +351,16 @@ const normalizeEasingAfterAddingKeyframe = ({ extraArgs, previousSegmentCount, n
|
|
|
353
351
|
? Math.min(insertedKeyframeIndex - 1, easing.length - 1)
|
|
354
352
|
: null;
|
|
355
353
|
easing.splice(insertedKeyframeIndex, 0, easingIndexToDuplicate === null
|
|
356
|
-
?
|
|
354
|
+
? defaultEasing
|
|
357
355
|
: easing[easingIndexToDuplicate]);
|
|
358
356
|
}
|
|
359
357
|
while (easing.length < nextSegmentCount) {
|
|
360
|
-
easing.push(
|
|
358
|
+
easing.push(defaultEasing);
|
|
361
359
|
}
|
|
360
|
+
const needsEasingImport = setEasingOption({ options, easing });
|
|
362
361
|
return {
|
|
363
362
|
extraArgs: getExtraArgsWithOptions({ extraArgs, options }),
|
|
364
|
-
needsEasingImport
|
|
363
|
+
needsEasingImport,
|
|
365
364
|
};
|
|
366
365
|
};
|
|
367
366
|
const getEasingIndexToRemove = ({ removedKeyframeIndex, keyframeCountBeforeRemoval, }) => {
|
|
@@ -586,6 +585,9 @@ const addKeyframe = ({ expression, key, frame, value, schema, videoConfigValues,
|
|
|
586
585
|
const existing = getInterpolationExpression(expression, videoConfigValues);
|
|
587
586
|
const newOutput = (0, update_nested_prop_1.parseValueExpression)(value);
|
|
588
587
|
if (existing) {
|
|
588
|
+
const defaultEasing = (0, studio_shared_1.isSchemaFieldHoldOnly)({ schema, key })
|
|
589
|
+
? studio_shared_1.HOLD_KEYFRAME_EASING
|
|
590
|
+
: studio_shared_1.LINEAR_KEYFRAME_EASING;
|
|
589
591
|
const existingCalleeName = existing.callee.type === 'Identifier'
|
|
590
592
|
? existing.callee.name
|
|
591
593
|
: 'interpolate';
|
|
@@ -619,6 +621,7 @@ const addKeyframe = ({ expression, key, frame, value, schema, videoConfigValues,
|
|
|
619
621
|
.sort((first, second) => first.frame - second.frame)
|
|
620
622
|
.findIndex((keyframe) => keyframe.frame === frame),
|
|
621
623
|
nextKeyframeCount: nextKeyframes.length,
|
|
624
|
+
defaultEasing,
|
|
622
625
|
})
|
|
623
626
|
: { extraArgs: existing.extraArgs, needsEasingImport: false };
|
|
624
627
|
return {
|
|
@@ -804,6 +807,10 @@ const applyKeyframeOperation = ({ expression, key, operation, schema, videoConfi
|
|
|
804
807
|
};
|
|
805
808
|
}
|
|
806
809
|
if (operation.type === 'easing') {
|
|
810
|
+
if ((0, studio_shared_1.isSchemaFieldHoldOnly)({ schema, key }) &&
|
|
811
|
+
operation.easing.type !== 'step1') {
|
|
812
|
+
throw new Error(`Cannot update easing: "${key}" only supports Easing.step1`);
|
|
813
|
+
}
|
|
807
814
|
const updated = updateKeyframeEasing({
|
|
808
815
|
expression,
|
|
809
816
|
segmentIndex: operation.segmentIndex,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { GitClientId } from '@remotion/studio-shared';
|
|
2
|
+
type SupportedGitClientPlatform = 'darwin' | 'win32';
|
|
3
|
+
export type InstalledGitClient = {
|
|
4
|
+
id: GitClientId;
|
|
5
|
+
name: string;
|
|
6
|
+
applicationPath: string;
|
|
7
|
+
platform: SupportedGitClientPlatform;
|
|
8
|
+
};
|
|
9
|
+
export type GitClientDiscoveryContext = {
|
|
10
|
+
platform: NodeJS.Platform;
|
|
11
|
+
env: NodeJS.ProcessEnv;
|
|
12
|
+
homeDirectory: string;
|
|
13
|
+
pathExists: (filePath: string) => boolean;
|
|
14
|
+
findMacApplications: (bundleIdentifier: string) => Promise<readonly string[]>;
|
|
15
|
+
findWindowsApplications: (directory: string) => readonly string[];
|
|
16
|
+
};
|
|
17
|
+
export declare const discoverAvailableGitClients: (context: GitClientDiscoveryContext) => Promise<readonly InstalledGitClient[]>;
|
|
18
|
+
export declare const getAvailableGitClients: () => Promise<readonly InstalledGitClient[]>;
|
|
19
|
+
export declare const getGitClientLaunchInstruction: ({ gitClient, remotionRoot, }: {
|
|
20
|
+
gitClient: InstalledGitClient;
|
|
21
|
+
remotionRoot: string;
|
|
22
|
+
}) => {
|
|
23
|
+
command: string;
|
|
24
|
+
args: string[];
|
|
25
|
+
};
|
|
26
|
+
export declare const launchGitClient: ({ gitClient, remotionRoot, }: {
|
|
27
|
+
gitClient: InstalledGitClient;
|
|
28
|
+
remotionRoot: string;
|
|
29
|
+
}) => Promise<void>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
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.launchGitClient = exports.getGitClientLaunchInstruction = exports.getAvailableGitClients = exports.discoverAvailableGitClients = void 0;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_os_1 = require("node:os");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const node_util_1 = require("node:util");
|
|
12
|
+
const bundler_1 = require("@remotion/bundler");
|
|
13
|
+
const execFilePromise = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
14
|
+
const findMacApplications = async (bundleIdentifier) => {
|
|
15
|
+
try {
|
|
16
|
+
const { stdout } = await execFilePromise('mdfind', [
|
|
17
|
+
`kMDItemCFBundleIdentifier == '${bundleIdentifier}'`,
|
|
18
|
+
]);
|
|
19
|
+
return stdout
|
|
20
|
+
.split('\n')
|
|
21
|
+
.map((line) => line.trim())
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
}
|
|
24
|
+
catch (_a) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const defaultDiscoveryContext = {
|
|
29
|
+
platform: process.platform,
|
|
30
|
+
env: process.env,
|
|
31
|
+
homeDirectory: (0, node_os_1.homedir)(),
|
|
32
|
+
pathExists: node_fs_1.existsSync,
|
|
33
|
+
findMacApplications,
|
|
34
|
+
findWindowsApplications: (directory) => {
|
|
35
|
+
try {
|
|
36
|
+
return (0, node_fs_1.readdirSync)(directory, { withFileTypes: true })
|
|
37
|
+
.filter((entry) => entry.isDirectory() && entry.name.startsWith('app-'))
|
|
38
|
+
.map((entry) => node_path_1.default.win32.join(directory, entry.name, 'GitHubDesktop.exe'))
|
|
39
|
+
.sort()
|
|
40
|
+
.reverse();
|
|
41
|
+
}
|
|
42
|
+
catch (_a) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const discoverAvailableGitClients = async (context) => {
|
|
48
|
+
if (context.platform === 'darwin') {
|
|
49
|
+
const discoveredApplications = await context.findMacApplications('com.github.GitHubClient');
|
|
50
|
+
const applicationPath = [
|
|
51
|
+
...new Set([
|
|
52
|
+
'/Applications/GitHub Desktop.app',
|
|
53
|
+
node_path_1.default.posix.join(context.homeDirectory, 'Applications/GitHub Desktop.app'),
|
|
54
|
+
...discoveredApplications,
|
|
55
|
+
]),
|
|
56
|
+
].find(context.pathExists);
|
|
57
|
+
return applicationPath
|
|
58
|
+
? [
|
|
59
|
+
{
|
|
60
|
+
applicationPath,
|
|
61
|
+
id: 'github-desktop',
|
|
62
|
+
name: 'GitHub Desktop',
|
|
63
|
+
platform: 'darwin',
|
|
64
|
+
},
|
|
65
|
+
]
|
|
66
|
+
: [];
|
|
67
|
+
}
|
|
68
|
+
if (context.platform === 'win32' && context.env.LOCALAPPDATA) {
|
|
69
|
+
const installationDirectory = node_path_1.default.win32.join(context.env.LOCALAPPDATA, 'GitHubDesktop');
|
|
70
|
+
const applicationPath = context
|
|
71
|
+
.findWindowsApplications(installationDirectory)
|
|
72
|
+
.find(context.pathExists);
|
|
73
|
+
return applicationPath
|
|
74
|
+
? [
|
|
75
|
+
{
|
|
76
|
+
applicationPath,
|
|
77
|
+
id: 'github-desktop',
|
|
78
|
+
name: 'GitHub Desktop',
|
|
79
|
+
platform: 'win32',
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
: [];
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
};
|
|
86
|
+
exports.discoverAvailableGitClients = discoverAvailableGitClients;
|
|
87
|
+
let availableGitClients = null;
|
|
88
|
+
const getAvailableGitClients = () => {
|
|
89
|
+
availableGitClients !== null && availableGitClients !== void 0 ? availableGitClients : (availableGitClients = (0, exports.discoverAvailableGitClients)(defaultDiscoveryContext));
|
|
90
|
+
return availableGitClients;
|
|
91
|
+
};
|
|
92
|
+
exports.getAvailableGitClients = getAvailableGitClients;
|
|
93
|
+
const getGitClientLaunchInstruction = ({ gitClient, remotionRoot, }) => {
|
|
94
|
+
var _a;
|
|
95
|
+
const repositoryRoot = (_a = bundler_1.BundlerInternals.findClosestFolderWithItem(remotionRoot, '.git')) !== null && _a !== void 0 ? _a : remotionRoot;
|
|
96
|
+
return gitClient.platform === 'darwin'
|
|
97
|
+
? {
|
|
98
|
+
command: 'open',
|
|
99
|
+
args: [
|
|
100
|
+
'-n',
|
|
101
|
+
gitClient.applicationPath,
|
|
102
|
+
'--args',
|
|
103
|
+
`--cli-open=${repositoryRoot}`,
|
|
104
|
+
],
|
|
105
|
+
}
|
|
106
|
+
: {
|
|
107
|
+
command: gitClient.applicationPath,
|
|
108
|
+
args: [`--cli-open=${repositoryRoot}`],
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
exports.getGitClientLaunchInstruction = getGitClientLaunchInstruction;
|
|
112
|
+
const launchGitClient = async ({ gitClient, remotionRoot, }) => {
|
|
113
|
+
const { command, args } = (0, exports.getGitClientLaunchInstruction)({
|
|
114
|
+
gitClient,
|
|
115
|
+
remotionRoot,
|
|
116
|
+
});
|
|
117
|
+
await new Promise((resolve, reject) => {
|
|
118
|
+
const child = (0, node_child_process_1.spawn)(command, args, {
|
|
119
|
+
cwd: remotionRoot,
|
|
120
|
+
detached: true,
|
|
121
|
+
stdio: 'ignore',
|
|
122
|
+
});
|
|
123
|
+
child.once('error', reject);
|
|
124
|
+
child.once('spawn', () => {
|
|
125
|
+
child.unref();
|
|
126
|
+
resolve();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
exports.launchGitClient = launchGitClient;
|