@remotion/studio-server 4.0.518 → 4.0.520
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/delete-jsx-node.d.ts +1 -4
- package/dist/codemods/duplicate-jsx-node.d.ts +11 -0
- package/dist/codemods/duplicate-jsx-node.js +11 -1
- package/dist/codemods/get-node-path-remappings.d.ts +1 -0
- package/dist/codemods/get-node-path-remappings.js +15 -2
- package/dist/codemods/split-video-from-audio.d.ts +1 -4
- package/dist/helpers/open-in-editor.js +1 -1
- package/dist/preview-server/api-routes.js +2 -0
- package/dist/preview-server/element-install-state.d.ts +0 -1
- package/dist/preview-server/element-install-state.js +1 -2
- package/dist/preview-server/routes/delete-jsx-node.js +0 -1
- package/dist/preview-server/routes/duplicate-jsx-node.js +71 -39
- package/dist/preview-server/routes/element-install-plan.d.ts +5 -11
- package/dist/preview-server/routes/element-install-plan.js +22 -9
- package/dist/preview-server/routes/insert-element.js +18 -10
- package/dist/preview-server/routes/insert-jsx-element.js +0 -1
- package/dist/preview-server/routes/prepare-element-install.js +7 -2
- package/dist/preview-server/routes/release-notes.d.ts +3 -0
- package/dist/preview-server/routes/release-notes.js +127 -0
- package/dist/preview-server/routes/reorder-sequence.js +0 -1
- package/dist/preview-server/routes/split-jsx-sequence.js +0 -1
- package/dist/preview-server/routes/split-video-from-audio.js +0 -1
- package/dist/preview-server/sequence-node-path-mutation.d.ts +0 -2
- package/dist/preview-server/start-server.js +9 -5
- package/dist/preview-server/studio-protocol/handle-discovery.js +2 -3
- package/dist/preview-server/studio-protocol/handle-element-library.js +6 -14
- package/dist/preview-server/studio-protocol/handle-install.js +16 -25
- package/dist/preview-server/studio-protocol/handle-license-key.js +5 -13
- package/dist/preview-server/undo-stack.js +4 -13
- package/package.json +8 -8
|
@@ -9,10 +9,7 @@ export declare const deleteJsxNodes: ({ input, nodePaths, }: {
|
|
|
9
9
|
formatted: boolean;
|
|
10
10
|
nodeLabels: string[];
|
|
11
11
|
logLines: number[];
|
|
12
|
-
nodePathRemappings:
|
|
13
|
-
oldNodePath: SequenceNodePath;
|
|
14
|
-
newNodePath: SequenceNodePath | null;
|
|
15
|
-
}[];
|
|
12
|
+
nodePathRemappings: import("@remotion/studio-shared").SequenceNodePathRemapping[];
|
|
16
13
|
}>;
|
|
17
14
|
export declare const deleteJsxNode: ({ input, nodePath, }: {
|
|
18
15
|
input: string;
|
|
@@ -12,3 +12,14 @@ export declare const duplicateJsxNode: ({ input, nodePath, prettierConfigOverrid
|
|
|
12
12
|
logLine: number;
|
|
13
13
|
nodePathRemappings: import("@remotion/studio-shared").SequenceNodePathRemapping[];
|
|
14
14
|
}>;
|
|
15
|
+
export declare const duplicateJsxNodes: ({ input, nodePaths, prettierConfigOverride, }: {
|
|
16
|
+
input: string;
|
|
17
|
+
nodePaths: SequenceNodePath[];
|
|
18
|
+
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
output: string;
|
|
21
|
+
formatted: boolean;
|
|
22
|
+
nodeLabels: string[];
|
|
23
|
+
logLines: number[];
|
|
24
|
+
nodePathRemappings: import("@remotion/studio-shared").SequenceNodePathRemapping[];
|
|
25
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.duplicateJsxNode = exports.duplicateJsxElementAtPath = void 0;
|
|
3
|
+
exports.duplicateJsxNodes = exports.duplicateJsxNode = exports.duplicateJsxElementAtPath = void 0;
|
|
4
4
|
const studio_codemods_1 = require("@remotion/studio-codemods");
|
|
5
5
|
Object.defineProperty(exports, "duplicateJsxElementAtPath", { enumerable: true, get: function () { return studio_codemods_1.duplicateJsxElementAtPath; } });
|
|
6
6
|
const format_file_content_1 = require("./format-file-content");
|
|
@@ -14,3 +14,13 @@ const duplicateJsxNode = ({ input, nodePath, prettierConfigOverride, }) => (0, s
|
|
|
14
14
|
prettierConfigOverride,
|
|
15
15
|
});
|
|
16
16
|
exports.duplicateJsxNode = duplicateJsxNode;
|
|
17
|
+
const duplicateJsxNodes = ({ input, nodePaths, prettierConfigOverride, }) => (0, studio_codemods_1.duplicateJsxNodes)({
|
|
18
|
+
input,
|
|
19
|
+
nodePaths,
|
|
20
|
+
formatFile: ({ contents, prettierConfigOverride: override }) => (0, format_file_content_1.formatFileContent)({
|
|
21
|
+
input: contents,
|
|
22
|
+
prettierConfigOverride: override,
|
|
23
|
+
}),
|
|
24
|
+
prettierConfigOverride,
|
|
25
|
+
});
|
|
26
|
+
exports.duplicateJsxNodes = duplicateJsxNodes;
|
|
@@ -4,6 +4,7 @@ import type { SequenceNodePath } from 'remotion';
|
|
|
4
4
|
export type CapturedJsxNodePath = {
|
|
5
5
|
node: JSXOpeningElement;
|
|
6
6
|
nodePath: SequenceNodePath;
|
|
7
|
+
signature: string;
|
|
7
8
|
};
|
|
8
9
|
export declare const captureJsxNodePaths: (ast: File) => CapturedJsxNodePath[];
|
|
9
10
|
export declare const getNodePathRemappings: ({ ast, captured, output, }: {
|
|
@@ -44,6 +44,7 @@ const captureJsxNodePaths = (ast) => {
|
|
|
44
44
|
captured.push({
|
|
45
45
|
node: path.node,
|
|
46
46
|
nodePath: (0, can_update_sequence_props_1.getNodePathForRecastPath)(path, ast),
|
|
47
|
+
signature: recast.prettyPrint(path.node).code,
|
|
47
48
|
});
|
|
48
49
|
return this.traverse(path);
|
|
49
50
|
},
|
|
@@ -74,15 +75,27 @@ const getNodePathRemappings = ({ ast, captured, output, }) => {
|
|
|
74
75
|
for (let i = 0; i < nodesAfterMutation.length; i++) {
|
|
75
76
|
finalNodePathByNode.set(nodesAfterMutation[i], finalNodePaths[i]);
|
|
76
77
|
}
|
|
77
|
-
const
|
|
78
|
+
const capturedNodes = new Set(captured.map(({ node }) => node));
|
|
79
|
+
const nodePathRemappings = captured.flatMap(({ node, nodePath, signature }) => {
|
|
78
80
|
var _a;
|
|
79
81
|
const newNodePath = (_a = finalNodePathByNode.get(node)) !== null && _a !== void 0 ? _a : null;
|
|
80
82
|
if (newNodePath !== null &&
|
|
81
|
-
JSON.stringify(nodePath) === JSON.stringify(newNodePath)
|
|
83
|
+
JSON.stringify(nodePath) === JSON.stringify(newNodePath) &&
|
|
84
|
+
recast.prettyPrint(node).code === signature) {
|
|
82
85
|
return [];
|
|
83
86
|
}
|
|
84
87
|
return [{ oldNodePath: nodePath, newNodePath }];
|
|
85
88
|
});
|
|
89
|
+
for (const node of nodesAfterMutation) {
|
|
90
|
+
if (capturedNodes.has(node)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const newNodePath = finalNodePathByNode.get(node);
|
|
94
|
+
if (!newNodePath) {
|
|
95
|
+
throw new Error('Could not map inserted JSX node path');
|
|
96
|
+
}
|
|
97
|
+
nodePathRemappings.push({ oldNodePath: null, newNodePath });
|
|
98
|
+
}
|
|
86
99
|
return { finalNodePathByNode, nodePathRemappings };
|
|
87
100
|
};
|
|
88
101
|
exports.getNodePathRemappings = getNodePathRemappings;
|
|
@@ -8,8 +8,5 @@ export declare const splitVideoFromAudio: ({ input, nodePath, prettierConfigOver
|
|
|
8
8
|
formatted: boolean;
|
|
9
9
|
nodeLabel: string;
|
|
10
10
|
logLine: number;
|
|
11
|
-
nodePathRemappings:
|
|
12
|
-
oldNodePath: SequenceNodePath;
|
|
13
|
-
newNodePath: SequenceNodePath | null;
|
|
14
|
-
}[];
|
|
11
|
+
nodePathRemappings: import("@remotion/studio-shared").SequenceNodePathRemapping[];
|
|
15
12
|
}>;
|
|
@@ -255,7 +255,7 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, colNumber) {
|
|
|
255
255
|
editor.endsWith('/Zed Preview.app/Contents/MacOS/cli');
|
|
256
256
|
const isFolder = node_fs_1.default.existsSync(fileName) && node_fs_1.default.lstatSync(fileName).isDirectory();
|
|
257
257
|
if (isZedEditor) {
|
|
258
|
-
return [fileName + ':' + lineNumber + ':' + colNumber];
|
|
258
|
+
return ['--existing', fileName + ':' + lineNumber + ':' + colNumber];
|
|
259
259
|
}
|
|
260
260
|
switch (editorBasename) {
|
|
261
261
|
case 'atom':
|
|
@@ -37,6 +37,7 @@ const prepare_element_install_1 = require("./routes/prepare-element-install");
|
|
|
37
37
|
const project_info_1 = require("./routes/project-info");
|
|
38
38
|
const redo_1 = require("./routes/redo");
|
|
39
39
|
const register_client_render_1 = require("./routes/register-client-render");
|
|
40
|
+
const release_notes_1 = require("./routes/release-notes");
|
|
40
41
|
const remotion_skills_info_1 = require("./routes/remotion-skills-info");
|
|
41
42
|
const remove_render_1 = require("./routes/remove-render");
|
|
42
43
|
const rename_static_file_1 = require("./routes/rename-static-file");
|
|
@@ -107,6 +108,7 @@ exports.allApiRoutes = {
|
|
|
107
108
|
'/api/split-jsx-sequence': split_jsx_sequence_1.splitJsxSequenceHandler,
|
|
108
109
|
'/api/split-video-from-audio': split_video_from_audio_1.splitVideoFromAudioHandler,
|
|
109
110
|
'/api/update-available': update_available_1.handleUpdate,
|
|
111
|
+
'/api/release-notes': release_notes_1.getReleaseNotesHandler,
|
|
110
112
|
'/api/remotion-skills-info': remotion_skills_info_1.remotionSkillsInfoHandler,
|
|
111
113
|
'/api/project-info': project_info_1.projectInfoHandler,
|
|
112
114
|
'/api/delete-static-file': delete_static_file_1.deleteStaticFileHandler,
|
|
@@ -80,8 +80,7 @@ const consumeStudioProtocolTarget = ({ now, origin, purpose, targetId, }) => {
|
|
|
80
80
|
if (purpose !== 'install-element') {
|
|
81
81
|
return issued.target;
|
|
82
82
|
}
|
|
83
|
-
if (
|
|
84
|
-
current.compositionFile !== issued.target.compositionFile ||
|
|
83
|
+
if (current.compositionFile !== issued.target.compositionFile ||
|
|
85
84
|
current.compositionId !== issued.target.compositionId) {
|
|
86
85
|
return null;
|
|
87
86
|
}
|
|
@@ -65,7 +65,6 @@ const deleteJsxNodeHandler = ({ input: { nodes }, remotionRoot, logLevel }) => {
|
|
|
65
65
|
const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(updates.map((update) => ({
|
|
66
66
|
absolutePath: update.absolutePath,
|
|
67
67
|
remappings: update.nodePathRemappings,
|
|
68
|
-
restoredNodePaths: [],
|
|
69
68
|
})));
|
|
70
69
|
for (const update of updates) {
|
|
71
70
|
const deletedNodeDescription = getDeletedNodeDescription(update.nodeLabels);
|
|
@@ -11,56 +11,88 @@ const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
|
|
|
11
11
|
const undo_stack_1 = require("../undo-stack");
|
|
12
12
|
const log_update_1 = require("./log-updates/log-update");
|
|
13
13
|
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
14
|
-
const duplicateJsxNodeHandler = ({ input: {
|
|
14
|
+
const duplicateJsxNodeHandler = ({ input: { nodes }, remotionRoot, logLevel }) => {
|
|
15
15
|
return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
16
|
+
var _a;
|
|
16
17
|
try {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
if (nodes.length === 0) {
|
|
19
|
+
throw new Error('No JSX nodes were specified for duplication');
|
|
20
|
+
}
|
|
21
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[duplicate-jsx-node] Received request to duplicate ${nodes.length} JSX node${nodes.length === 1 ? '' : 's'}`);
|
|
22
|
+
const itemsByFileName = new Map();
|
|
23
|
+
for (const item of nodes) {
|
|
24
|
+
const fileItems = (_a = itemsByFileName.get(item.fileName)) !== null && _a !== void 0 ? _a : [];
|
|
25
|
+
fileItems.push(item);
|
|
26
|
+
itemsByFileName.set(item.fileName, fileItems);
|
|
27
|
+
}
|
|
28
|
+
const updates = await Promise.all([...itemsByFileName.entries()].map(async ([fileName, fileItems]) => {
|
|
29
|
+
const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
30
|
+
remotionRoot,
|
|
31
|
+
fileName,
|
|
32
|
+
action: 'modify',
|
|
33
|
+
});
|
|
34
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
35
|
+
const { output, formatted, nodeLabels, logLines, nodePathRemappings } = await (0, duplicate_jsx_node_1.duplicateJsxNodes)({
|
|
36
|
+
input: fileContents,
|
|
37
|
+
nodePaths: fileItems.map((item) => item.nodePath),
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
27
40
|
absolutePath,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
fileRelativeToRoot,
|
|
42
|
+
fileContents,
|
|
43
|
+
formatted,
|
|
44
|
+
logLine: Math.min(...logLines),
|
|
45
|
+
nodeLabels,
|
|
46
|
+
nodePathRemappings,
|
|
47
|
+
output,
|
|
48
|
+
};
|
|
49
|
+
}));
|
|
50
|
+
const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(updates.map((update) => ({
|
|
51
|
+
absolutePath: update.absolutePath,
|
|
52
|
+
remappings: update.nodePathRemappings,
|
|
53
|
+
})));
|
|
54
|
+
const duplicatedNodeDescription = nodes.length === 1
|
|
55
|
+
? updates[0].nodeLabels[0]
|
|
56
|
+
: `${nodes.length} JSX nodes`;
|
|
57
|
+
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
58
|
+
snapshots: updates.map((update) => ({
|
|
59
|
+
filePath: update.absolutePath,
|
|
60
|
+
oldContents: update.fileContents,
|
|
61
|
+
newContents: null,
|
|
62
|
+
logLine: update.logLine,
|
|
63
|
+
nodePathRemappings: update.nodePathRemappings,
|
|
64
|
+
})),
|
|
36
65
|
logLevel,
|
|
37
66
|
remotionRoot,
|
|
38
|
-
logLine,
|
|
39
67
|
description: {
|
|
40
|
-
undoMessage: `↩️ Duplication of ${
|
|
41
|
-
redoMessage: `↪️ Duplication of ${
|
|
68
|
+
undoMessage: `↩️ Duplication of ${duplicatedNodeDescription}`,
|
|
69
|
+
redoMessage: `↪️ Duplication of ${duplicatedNodeDescription}`,
|
|
42
70
|
},
|
|
43
71
|
entryType: 'duplicate-jsx-node',
|
|
44
72
|
suppressHmrOnFileRestore: false,
|
|
45
|
-
nodePathRemappings,
|
|
46
|
-
});
|
|
47
|
-
(0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
|
|
48
|
-
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
49
|
-
file: absolutePath,
|
|
50
|
-
content: output,
|
|
51
|
-
originatorClientId: undefined,
|
|
52
|
-
metadata: { skipSequencePropsUpdate: true },
|
|
53
|
-
});
|
|
54
|
-
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
55
|
-
remotionRoot,
|
|
56
|
-
absolutePath,
|
|
57
|
-
line: logLine,
|
|
58
73
|
});
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
(0,
|
|
74
|
+
for (const update of updates) {
|
|
75
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(update.absolutePath);
|
|
76
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)({
|
|
77
|
+
file: update.absolutePath,
|
|
78
|
+
content: update.output,
|
|
79
|
+
originatorClientId: undefined,
|
|
80
|
+
metadata: { skipSequencePropsUpdate: true },
|
|
81
|
+
});
|
|
82
|
+
const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
|
|
83
|
+
remotionRoot,
|
|
84
|
+
absolutePath: update.absolutePath,
|
|
85
|
+
line: update.logLine,
|
|
86
|
+
});
|
|
87
|
+
const fileDescription = update.nodeLabels.length === 1
|
|
88
|
+
? update.nodeLabels[0]
|
|
89
|
+
: `${update.nodeLabels.length} JSX nodes`;
|
|
90
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Duplicated ${fileDescription}`);
|
|
91
|
+
if (!update.formatted) {
|
|
92
|
+
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
93
|
+
}
|
|
94
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[duplicate-jsx-node] Wrote ${update.fileRelativeToRoot}${update.formatted ? ' (formatted)' : ''}`);
|
|
62
95
|
}
|
|
63
|
-
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[duplicate-jsx-node] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
|
|
64
96
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
65
97
|
return {
|
|
66
98
|
success: true,
|
|
@@ -2,30 +2,24 @@ import type { ElementInstallExpectedFileState, PrepareElementInstallRequest } fr
|
|
|
2
2
|
export declare const normalizeElementSourceForComparison: (source: string) => string;
|
|
3
3
|
export declare const getElementSourceHash: (source: string) => string;
|
|
4
4
|
export declare const validateElementInstallPosition: (position: import("@remotion/studio-shared").InsertableCompositionElementPosition | null) => void;
|
|
5
|
-
export declare const validateElementForInstallation: (element:
|
|
6
|
-
dependencies: import("@remotion/studio-protocol").ElementDependency[];
|
|
7
|
-
durationInFrames?: number | undefined;
|
|
8
|
-
installationMode?: import("@remotion/studio-protocol").ElementInstallationMode | undefined;
|
|
9
|
-
slug: string;
|
|
10
|
-
displayName: string;
|
|
11
|
-
sourceCode: string;
|
|
12
|
-
dimensions: import("@remotion/studio-protocol").ComponentDimensions | null;
|
|
13
|
-
}) => void;
|
|
5
|
+
export declare const validateElementForInstallation: (element: import("@remotion/studio-shared").InstallableElement) => void;
|
|
14
6
|
export declare const makeRelativeElementImportPath: ({ fromFile, toFile, }: {
|
|
15
7
|
fromFile: string;
|
|
16
8
|
toFile: string;
|
|
17
9
|
}) => string;
|
|
18
|
-
export declare const getElementInstallPlan: ({
|
|
10
|
+
export declare const getElementInstallPlan: ({ destination, element, entryPoint, remotionRoot, }: PrepareElementInstallRequest & {
|
|
11
|
+
entryPoint: string;
|
|
19
12
|
remotionRoot: string;
|
|
20
13
|
}) => Promise<{
|
|
21
14
|
componentName: string;
|
|
15
|
+
destinationCompositionFileName: string;
|
|
22
16
|
elementFileExists: boolean;
|
|
23
17
|
elementFileName: string;
|
|
24
18
|
existingElementSource: string | null;
|
|
25
19
|
expectedFileState: ElementInstallExpectedFileState;
|
|
26
20
|
filePath: string;
|
|
27
21
|
importPath: string;
|
|
28
|
-
location: import("@remotion/studio-codemods").ResolvedCompositionComponentWithFile;
|
|
22
|
+
location: import("@remotion/studio-codemods").ResolvedCompositionComponentWithFile | null;
|
|
29
23
|
safePaths: {
|
|
30
24
|
compositionFileName: string;
|
|
31
25
|
elementFileName: string;
|
|
@@ -9,6 +9,7 @@ const node_fs_1 = require("node:fs");
|
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
10
|
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
11
11
|
const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
|
|
12
|
+
const project_info_1 = require("../project-info");
|
|
12
13
|
const safe_element_install_path_1 = require("./safe-element-install-path");
|
|
13
14
|
const normalizeElementSourceForComparison = (source) => {
|
|
14
15
|
return source.replace(/\r\n/g, '\n').trim();
|
|
@@ -74,27 +75,38 @@ const getExpectedFileState = (existingSource) => {
|
|
|
74
75
|
sourceHash: (0, exports.getElementSourceHash)(existingSource),
|
|
75
76
|
};
|
|
76
77
|
};
|
|
77
|
-
const getElementInstallPlan = async ({
|
|
78
|
+
const getElementInstallPlan = async ({ destination, element, entryPoint, remotionRoot, }) => {
|
|
79
|
+
var _a;
|
|
78
80
|
(0, exports.validateElementForInstallation)(element);
|
|
79
81
|
const componentName = studio_protocol_1.StudioProtocolInternals.getElementComponentNameFromSourceCode(element.sourceCode);
|
|
80
82
|
if (componentName === null) {
|
|
81
83
|
throw new Error('Element source must export exactly one named component');
|
|
82
84
|
}
|
|
83
|
-
const location =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
const location = destination.type === 'current-composition'
|
|
86
|
+
? await (0, resolve_composition_component_1.resolveCompositionComponentWithFile)({
|
|
87
|
+
remotionRoot,
|
|
88
|
+
compositionFile: destination.compositionFile,
|
|
89
|
+
compositionId: destination.compositionId,
|
|
90
|
+
})
|
|
91
|
+
: null;
|
|
92
|
+
if (location !== null && !location.canAddSequence) {
|
|
89
93
|
throw new Error('Cannot insert Element into this composition component');
|
|
90
94
|
}
|
|
91
95
|
const derivedElementFileName = studio_protocol_1.StudioProtocolInternals.makeElementFileNameFromSlug(element.slug);
|
|
92
96
|
if (derivedElementFileName === null) {
|
|
93
97
|
throw new Error('Element slug must produce a safe lowercase .tsx file name');
|
|
94
98
|
}
|
|
99
|
+
const destinationCompositionFile = destination.compositionFile;
|
|
100
|
+
const destinationCompositionFileName = destinationCompositionFile === null
|
|
101
|
+
? (await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint)).rootFile
|
|
102
|
+
: node_path_1.default.resolve(remotionRoot, destinationCompositionFile);
|
|
103
|
+
if (destinationCompositionFileName === null) {
|
|
104
|
+
throw new Error('Could not find the root file of the project');
|
|
105
|
+
}
|
|
106
|
+
const compositionFileName = (_a = location === null || location === void 0 ? void 0 : location.fileName) !== null && _a !== void 0 ? _a : destinationCompositionFileName;
|
|
95
107
|
const safePaths = await (0, safe_element_install_path_1.getSafeElementInstallPaths)({
|
|
96
|
-
compositionFileName
|
|
97
|
-
elementFileName: node_path_1.default.resolve(node_path_1.default.dirname(
|
|
108
|
+
compositionFileName,
|
|
109
|
+
elementFileName: node_path_1.default.resolve(node_path_1.default.dirname(compositionFileName), derivedElementFileName),
|
|
98
110
|
remotionRoot,
|
|
99
111
|
});
|
|
100
112
|
const elementFileExists = (0, node_fs_1.existsSync)(safePaths.elementFileName);
|
|
@@ -103,6 +115,7 @@ const getElementInstallPlan = async ({ compositionFile, compositionId, element,
|
|
|
103
115
|
: null;
|
|
104
116
|
return {
|
|
105
117
|
componentName,
|
|
118
|
+
destinationCompositionFileName,
|
|
106
119
|
elementFileExists,
|
|
107
120
|
elementFileName: safePaths.elementFileName,
|
|
108
121
|
existingElementSource,
|
|
@@ -22,21 +22,26 @@ const hasExpectedFileState = ({ expected, actual, }) => {
|
|
|
22
22
|
}
|
|
23
23
|
return actual.sourceHash === expected.sourceHash;
|
|
24
24
|
};
|
|
25
|
-
const insertElementHandler = ({ input: { compositionFile, compositionId, element, expectedFileState, from, position, overwriteExisting, }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
26
|
-
var _a, _b;
|
|
25
|
+
const insertElementHandler = ({ input: { compositionFile, compositionId, element, expectedFileState, from, position, overwriteExisting, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
27
26
|
try {
|
|
28
27
|
(0, element_install_plan_1.validateElementInstallPosition)(position);
|
|
29
28
|
if (from !== null &&
|
|
30
29
|
(!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
|
|
31
30
|
throw new Error('from must be a non-negative integer');
|
|
32
31
|
}
|
|
33
|
-
const installationMode =
|
|
32
|
+
const installationMode = element.installationMode === null
|
|
33
|
+
? 'wrapped'
|
|
34
|
+
: element.installationMode;
|
|
34
35
|
const componentOwnsSequence = installationMode === 'component-owned-sequence';
|
|
35
36
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
|
|
36
37
|
const plan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
destination: {
|
|
39
|
+
type: 'current-composition',
|
|
40
|
+
compositionFile,
|
|
41
|
+
compositionId,
|
|
42
|
+
},
|
|
39
43
|
element,
|
|
44
|
+
entryPoint,
|
|
40
45
|
remotionRoot,
|
|
41
46
|
});
|
|
42
47
|
if (expectedFileState !== null &&
|
|
@@ -86,7 +91,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
86
91
|
importPath: plan.importPath,
|
|
87
92
|
props: componentOwnsSequence
|
|
88
93
|
? [
|
|
89
|
-
...(element.durationInFrames ===
|
|
94
|
+
...(element.durationInFrames === null
|
|
90
95
|
? []
|
|
91
96
|
: [
|
|
92
97
|
{
|
|
@@ -105,16 +110,20 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
105
110
|
? null
|
|
106
111
|
: {
|
|
107
112
|
dimensions: element.dimensions,
|
|
108
|
-
durationInFrames:
|
|
113
|
+
durationInFrames: element.durationInFrames,
|
|
109
114
|
from,
|
|
110
115
|
name: element.displayName,
|
|
111
116
|
position,
|
|
112
117
|
},
|
|
113
118
|
});
|
|
114
119
|
const finalPlan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
destination: {
|
|
121
|
+
type: 'current-composition',
|
|
122
|
+
compositionFile,
|
|
123
|
+
compositionId,
|
|
124
|
+
},
|
|
117
125
|
element,
|
|
126
|
+
entryPoint,
|
|
118
127
|
remotionRoot,
|
|
119
128
|
});
|
|
120
129
|
if (finalPlan.safePaths.compositionFileName !==
|
|
@@ -131,7 +140,6 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
131
140
|
{
|
|
132
141
|
absolutePath: inserted.fileName,
|
|
133
142
|
remappings: inserted.nodePathRemappings,
|
|
134
|
-
restoredNodePaths: [],
|
|
135
143
|
},
|
|
136
144
|
]);
|
|
137
145
|
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
@@ -3,12 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.prepareElementInstallHandler = void 0;
|
|
4
4
|
const element_install_plan_1 = require("./element-install-plan");
|
|
5
5
|
const source_file_write_queue_1 = require("./source-file-write-queue");
|
|
6
|
-
const prepareElementInstallHandler = ({ input, remotionRoot }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
6
|
+
const prepareElementInstallHandler = ({ entryPoint, input, remotionRoot }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
7
7
|
try {
|
|
8
|
-
const plan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
8
|
+
const plan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
9
|
+
...input,
|
|
10
|
+
entryPoint,
|
|
11
|
+
remotionRoot,
|
|
12
|
+
});
|
|
9
13
|
return {
|
|
10
14
|
success: true,
|
|
11
15
|
plan: {
|
|
16
|
+
compositionFile: plan.destinationCompositionFileName,
|
|
12
17
|
expectedFileState: plan.expectedFileState,
|
|
13
18
|
filePath: plan.filePath,
|
|
14
19
|
},
|
|
@@ -0,0 +1,127 @@
|
|
|
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.getReleaseNotesHandler = void 0;
|
|
7
|
+
const semver_1 = __importDefault(require("semver"));
|
|
8
|
+
const githubApiVersion = '2022-11-28';
|
|
9
|
+
const releaseNotesTimeout = 5000;
|
|
10
|
+
const releaseNotesCacheDuration = 5 * 60 * 1000;
|
|
11
|
+
const maximumReleaseNotes = 5;
|
|
12
|
+
const releaseNotesCache = new Map();
|
|
13
|
+
const getReleaseNotesHandler = async ({ input }) => {
|
|
14
|
+
const currentVersion = semver_1.default.valid(input.currentVersion);
|
|
15
|
+
const latestVersion = semver_1.default.valid(input.latestVersion);
|
|
16
|
+
if (currentVersion === null || latestVersion === null) {
|
|
17
|
+
throw new Error(`Invalid Remotion version range: ${input.currentVersion} to ${input.latestVersion}`);
|
|
18
|
+
}
|
|
19
|
+
const cacheKey = `${currentVersion}:${latestVersion}`;
|
|
20
|
+
const cachedReleaseNotes = releaseNotesCache.get(cacheKey);
|
|
21
|
+
if (cachedReleaseNotes && cachedReleaseNotes.expiresAt > Date.now()) {
|
|
22
|
+
return cachedReleaseNotes.response;
|
|
23
|
+
}
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const timeout = setTimeout(() => controller.abort(), releaseNotesTimeout);
|
|
26
|
+
try {
|
|
27
|
+
const releaseResponse = await fetch('https://api.github.com/repos/remotion-dev/remotion/releases?per_page=100', {
|
|
28
|
+
headers: {
|
|
29
|
+
accept: 'application/vnd.github+json',
|
|
30
|
+
'user-agent': 'Remotion Studio',
|
|
31
|
+
'x-github-api-version': githubApiVersion,
|
|
32
|
+
},
|
|
33
|
+
signal: controller.signal,
|
|
34
|
+
});
|
|
35
|
+
if (!releaseResponse.ok) {
|
|
36
|
+
return { hasMore: false, releases: [] };
|
|
37
|
+
}
|
|
38
|
+
const githubReleases = (await releaseResponse.json());
|
|
39
|
+
if (!Array.isArray(githubReleases)) {
|
|
40
|
+
return { hasMore: false, releases: [] };
|
|
41
|
+
}
|
|
42
|
+
const matchingReleases = githubReleases
|
|
43
|
+
.flatMap((release) => {
|
|
44
|
+
if (typeof release !== 'object' || release === null) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
const { body, published_at: publishedAt, tag_name: tagName, } = release;
|
|
48
|
+
if (typeof tagName !== 'string') {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
const version = semver_1.default.valid(tagName.startsWith('v') ? tagName.slice(1) : tagName);
|
|
52
|
+
if (version === null ||
|
|
53
|
+
!semver_1.default.gt(version, currentVersion) ||
|
|
54
|
+
!semver_1.default.lte(version, latestVersion)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
body: typeof body === 'string' ? body : null,
|
|
60
|
+
publishedAt: typeof publishedAt === 'string' ? publishedAt : null,
|
|
61
|
+
version,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
})
|
|
65
|
+
.sort((a, b) => semver_1.default.rcompare(a.version, b.version));
|
|
66
|
+
const hasMore = matchingReleases.length > maximumReleaseNotes;
|
|
67
|
+
const releases = await Promise.all(matchingReleases.slice(0, maximumReleaseNotes).map(async (release) => {
|
|
68
|
+
if (release.body === null || release.body.trim() === '') {
|
|
69
|
+
return {
|
|
70
|
+
publishedAt: release.publishedAt,
|
|
71
|
+
releaseNotesHtml: null,
|
|
72
|
+
version: release.version,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const markdownResponse = await fetch('https://api.github.com/markdown', {
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
context: 'remotion-dev/remotion',
|
|
79
|
+
mode: 'gfm',
|
|
80
|
+
text: release.body,
|
|
81
|
+
}),
|
|
82
|
+
headers: {
|
|
83
|
+
accept: 'text/html',
|
|
84
|
+
'content-type': 'application/json',
|
|
85
|
+
'user-agent': 'Remotion Studio',
|
|
86
|
+
'x-github-api-version': githubApiVersion,
|
|
87
|
+
},
|
|
88
|
+
method: 'POST',
|
|
89
|
+
signal: controller.signal,
|
|
90
|
+
});
|
|
91
|
+
if (!markdownResponse.ok) {
|
|
92
|
+
return {
|
|
93
|
+
publishedAt: release.publishedAt,
|
|
94
|
+
releaseNotesHtml: null,
|
|
95
|
+
version: release.version,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const releaseNotesHtml = await markdownResponse.text();
|
|
99
|
+
return {
|
|
100
|
+
publishedAt: release.publishedAt,
|
|
101
|
+
releaseNotesHtml: releaseNotesHtml || null,
|
|
102
|
+
version: release.version,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (_a) {
|
|
106
|
+
return {
|
|
107
|
+
publishedAt: release.publishedAt,
|
|
108
|
+
releaseNotesHtml: null,
|
|
109
|
+
version: release.version,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}));
|
|
113
|
+
const response = { hasMore, releases };
|
|
114
|
+
releaseNotesCache.set(cacheKey, {
|
|
115
|
+
expiresAt: Date.now() + releaseNotesCacheDuration,
|
|
116
|
+
response,
|
|
117
|
+
});
|
|
118
|
+
return response;
|
|
119
|
+
}
|
|
120
|
+
catch (_a) {
|
|
121
|
+
return { hasMore: false, releases: [] };
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
clearTimeout(timeout);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
exports.getReleaseNotesHandler = getReleaseNotesHandler;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { SequenceNodePathMutation, SequenceNodePathRemapping } from '@remotion/studio-shared';
|
|
2
|
-
import type { SequenceNodePath } from 'remotion';
|
|
3
2
|
export declare const broadcastSequenceNodePathMutation: (files: {
|
|
4
3
|
absolutePath: string;
|
|
5
4
|
remappings: SequenceNodePathRemapping[];
|
|
6
|
-
restoredNodePaths: SequenceNodePath[];
|
|
7
5
|
}[]) => SequenceNodePathMutation;
|
|
@@ -19,16 +19,20 @@ const startServer = async (options) => {
|
|
|
19
19
|
var _a, _b;
|
|
20
20
|
const desiredPort = (_b = (_a = options === null || options === void 0 ? void 0 : options.port) !== null && _a !== void 0 ? _a : (process.env.PORT ? Number(process.env.PORT) : undefined)) !== null && _b !== void 0 ? _b : undefined;
|
|
21
21
|
const portConfig = renderer_1.RenderInternals.getPortConfig(options.forceIPv4);
|
|
22
|
-
const onPortUnavailable =
|
|
23
|
-
|
|
24
|
-
: async (port) => {
|
|
22
|
+
const onPortUnavailable = async (port) => {
|
|
23
|
+
if (!options.forceNew) {
|
|
25
24
|
const detection = await (0, detect_remotion_server_1.detectRemotionServer)({
|
|
26
25
|
port,
|
|
27
26
|
cwd: options.remotionRoot,
|
|
28
27
|
hostname: portConfig.hostsToTry[0],
|
|
29
28
|
});
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if (detection.type === 'match') {
|
|
30
|
+
return 'stop';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel: options.logLevel }, renderer_1.RenderInternals.chalk.gray(`Port ${port} is busy, trying another.`));
|
|
34
|
+
return 'continue';
|
|
35
|
+
};
|
|
32
36
|
let portSelection = await renderer_1.RenderInternals.getDesiredPort({
|
|
33
37
|
desiredPort,
|
|
34
38
|
from: 3000,
|
|
@@ -32,8 +32,7 @@ const getLiveStudioTarget = (requestId) => {
|
|
|
32
32
|
}
|
|
33
33
|
return target;
|
|
34
34
|
};
|
|
35
|
-
const
|
|
36
|
-
target.canInstall &&
|
|
35
|
+
const isElementRequestTarget = (target) => target !== null &&
|
|
37
36
|
target.compositionFile !== null &&
|
|
38
37
|
target.compositionId !== null &&
|
|
39
38
|
target.lastFocusedAt !== null;
|
|
@@ -68,7 +67,7 @@ const handleStudioProtocolDiscovery = ({ gitSource, liveEventsServer, remotionRo
|
|
|
68
67
|
setTimeout(() => {
|
|
69
68
|
const now = Date.now();
|
|
70
69
|
const target = getLiveStudioTarget(requestId);
|
|
71
|
-
const installTarget =
|
|
70
|
+
const installTarget = isElementRequestTarget(target) ? target : null;
|
|
72
71
|
const issuedInstallTarget = installTarget === null
|
|
73
72
|
? null
|
|
74
73
|
: (0, element_install_state_1.issueStudioProtocolTarget)({
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleStudioProtocolElementLibrary = void 0;
|
|
4
|
-
const
|
|
4
|
+
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
5
5
|
const element_install_state_1 = require("../element-install-state");
|
|
6
6
|
const parse_body_1 = require("../parse-body");
|
|
7
7
|
const origin_policy_1 = require("./origin-policy");
|
|
8
8
|
const protocol_response_1 = require("./protocol-response");
|
|
9
|
-
const studioProtocolElementLibraryRequestSchema = zod_1.z.object({
|
|
10
|
-
operation: zod_1.z.literal('add-element-library'),
|
|
11
|
-
protocol: zod_1.z.literal('remotion-studio-protocol'),
|
|
12
|
-
protocolVersion: zod_1.z.literal(1),
|
|
13
|
-
targetId: zod_1.z.string().min(1),
|
|
14
|
-
url: zod_1.z.string(),
|
|
15
|
-
displayName: zod_1.z.string().nullable(),
|
|
16
|
-
});
|
|
17
9
|
const MAX_STUDIO_PROTOCOL_ELEMENT_LIBRARY_BODY_SIZE = 16 * 1024;
|
|
18
10
|
const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab, liveEventsServer, request, response, }) => {
|
|
19
11
|
var _a;
|
|
@@ -62,8 +54,8 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
|
|
|
62
54
|
});
|
|
63
55
|
return;
|
|
64
56
|
}
|
|
65
|
-
const parsedRequest =
|
|
66
|
-
if (
|
|
57
|
+
const parsedRequest = studio_protocol_1.StudioProtocolInternals.parseStudioProtocolAddElementLibraryRequest(body);
|
|
58
|
+
if (parsedRequest === null) {
|
|
67
59
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
68
60
|
code: 'unsupported-protocol',
|
|
69
61
|
message: 'Invalid Remotion Studio Protocol request.',
|
|
@@ -74,7 +66,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
|
|
|
74
66
|
}
|
|
75
67
|
let normalizedUrl;
|
|
76
68
|
try {
|
|
77
|
-
const parsedUrl = new URL(parsedRequest.
|
|
69
|
+
const parsedUrl = new URL(parsedRequest.url);
|
|
78
70
|
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
79
71
|
throw new Error('Unsupported protocol');
|
|
80
72
|
}
|
|
@@ -89,7 +81,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
|
|
|
89
81
|
});
|
|
90
82
|
return;
|
|
91
83
|
}
|
|
92
|
-
const displayName = (_b = (_a = parsedRequest.
|
|
84
|
+
const displayName = (_b = (_a = parsedRequest.displayName) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : null;
|
|
93
85
|
if (displayName === '') {
|
|
94
86
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
95
87
|
code: 'invalid-display-name',
|
|
@@ -103,7 +95,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
|
|
|
103
95
|
now: Date.now(),
|
|
104
96
|
origin: requestOrigin,
|
|
105
97
|
purpose: 'add-element-library',
|
|
106
|
-
targetId: parsedRequest.
|
|
98
|
+
targetId: parsedRequest.targetId,
|
|
107
99
|
});
|
|
108
100
|
if (target === null) {
|
|
109
101
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
@@ -2,22 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleStudioProtocolInstall = void 0;
|
|
4
4
|
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
5
|
-
const zod_1 = require("zod");
|
|
6
5
|
const element_install_state_1 = require("../element-install-state");
|
|
7
6
|
const parse_body_1 = require("../parse-body");
|
|
8
7
|
const origin_policy_1 = require("./origin-policy");
|
|
9
8
|
const protocol_response_1 = require("./protocol-response");
|
|
10
|
-
const studioProtocolInstallRequestSchema = zod_1.z.object({
|
|
11
|
-
operation: zod_1.z.literal('install-element'),
|
|
12
|
-
protocol: zod_1.z.literal('remotion-studio-protocol'),
|
|
13
|
-
protocolVersion: zod_1.z.literal(1),
|
|
14
|
-
targetId: zod_1.z.string(),
|
|
15
|
-
payload: zod_1.z.unknown(),
|
|
16
|
-
});
|
|
17
9
|
// A valid payload may contain 250,000 JSON characters. Allow room for its
|
|
18
10
|
// UTF-8 representation and the protocol envelope while keeping memory bounded.
|
|
19
11
|
const MAX_STUDIO_PROTOCOL_INSTALL_BODY_SIZE = 1000000;
|
|
20
12
|
const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, origin, target, }) => {
|
|
13
|
+
var _a, _b;
|
|
21
14
|
if (target.compositionFile === null || target.compositionId === null) {
|
|
22
15
|
return false;
|
|
23
16
|
}
|
|
@@ -27,7 +20,11 @@ const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, orig
|
|
|
27
20
|
createdAt: Date.now(),
|
|
28
21
|
compositionFile: target.compositionFile,
|
|
29
22
|
compositionId: target.compositionId,
|
|
30
|
-
element
|
|
23
|
+
element: {
|
|
24
|
+
...element,
|
|
25
|
+
durationInFrames: (_a = element.durationInFrames) !== null && _a !== void 0 ? _a : null,
|
|
26
|
+
installationMode: (_b = element.installationMode) !== null && _b !== void 0 ? _b : null,
|
|
27
|
+
},
|
|
31
28
|
from: null,
|
|
32
29
|
position: null,
|
|
33
30
|
source: {
|
|
@@ -89,21 +86,15 @@ const handleStudioProtocolInstall = async ({ focusStudioTab, liveEventsServer, r
|
|
|
89
86
|
});
|
|
90
87
|
return;
|
|
91
88
|
}
|
|
92
|
-
const parsedRequest =
|
|
93
|
-
if (
|
|
94
|
-
(0, protocol_response_1.writeStudioProtocolError)({
|
|
95
|
-
code: 'unsupported-protocol',
|
|
96
|
-
message: 'Invalid Remotion Studio Protocol request.',
|
|
97
|
-
response,
|
|
98
|
-
status: 400,
|
|
99
|
-
});
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const payload = studio_protocol_1.StudioProtocolInternals.parseStudioElementPayload(parsedRequest.data.payload);
|
|
103
|
-
if (payload === null) {
|
|
89
|
+
const parsedRequest = studio_protocol_1.StudioProtocolInternals.parseStudioProtocolInstallRequest(body);
|
|
90
|
+
if (parsedRequest.status !== 'valid') {
|
|
104
91
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
105
|
-
code: 'invalid-payload'
|
|
106
|
-
|
|
92
|
+
code: parsedRequest.status === 'invalid-payload'
|
|
93
|
+
? 'invalid-payload'
|
|
94
|
+
: 'unsupported-protocol',
|
|
95
|
+
message: parsedRequest.status === 'invalid-payload'
|
|
96
|
+
? 'Invalid Element payload.'
|
|
97
|
+
: 'Invalid Remotion Studio Protocol request.',
|
|
107
98
|
response,
|
|
108
99
|
status: 400,
|
|
109
100
|
});
|
|
@@ -113,7 +104,7 @@ const handleStudioProtocolInstall = async ({ focusStudioTab, liveEventsServer, r
|
|
|
113
104
|
now: Date.now(),
|
|
114
105
|
origin: requestOrigin,
|
|
115
106
|
purpose: 'install-element',
|
|
116
|
-
targetId: parsedRequest.
|
|
107
|
+
targetId: parsedRequest.request.targetId,
|
|
117
108
|
});
|
|
118
109
|
if (target === null) {
|
|
119
110
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
@@ -125,7 +116,7 @@ const handleStudioProtocolInstall = async ({ focusStudioTab, liveEventsServer, r
|
|
|
125
116
|
return;
|
|
126
117
|
}
|
|
127
118
|
if (!deliverElementInstall({
|
|
128
|
-
element: payload.element,
|
|
119
|
+
element: parsedRequest.request.payload.element,
|
|
129
120
|
focusStudioTab,
|
|
130
121
|
liveEventsServer,
|
|
131
122
|
origin: requestOrigin,
|
|
@@ -2,18 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleStudioProtocolLicenseKey = void 0;
|
|
4
4
|
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
5
|
-
const zod_1 = require("zod");
|
|
6
5
|
const element_install_state_1 = require("../element-install-state");
|
|
7
6
|
const parse_body_1 = require("../parse-body");
|
|
8
7
|
const origin_policy_1 = require("./origin-policy");
|
|
9
8
|
const protocol_response_1 = require("./protocol-response");
|
|
10
|
-
const studioProtocolLicenseKeyRequestSchema = zod_1.z.object({
|
|
11
|
-
operation: zod_1.z.literal('set-license-key'),
|
|
12
|
-
protocol: zod_1.z.literal('remotion-studio-protocol'),
|
|
13
|
-
protocolVersion: zod_1.z.literal(1),
|
|
14
|
-
targetId: zod_1.z.string().min(1),
|
|
15
|
-
licenseKey: zod_1.z.string(),
|
|
16
|
-
});
|
|
17
9
|
const MAX_STUDIO_PROTOCOL_LICENSE_KEY_BODY_SIZE = 4096;
|
|
18
10
|
const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, liveEventsServer, request, response, }) => {
|
|
19
11
|
(0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
|
|
@@ -60,8 +52,8 @@ const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, live
|
|
|
60
52
|
});
|
|
61
53
|
return;
|
|
62
54
|
}
|
|
63
|
-
const parsedRequest =
|
|
64
|
-
if (
|
|
55
|
+
const parsedRequest = studio_protocol_1.StudioProtocolInternals.parseStudioProtocolSetLicenseKeyRequest(body);
|
|
56
|
+
if (parsedRequest === null) {
|
|
65
57
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
66
58
|
code: 'unsupported-protocol',
|
|
67
59
|
message: 'Invalid Remotion Studio Protocol request.',
|
|
@@ -70,7 +62,7 @@ const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, live
|
|
|
70
62
|
});
|
|
71
63
|
return;
|
|
72
64
|
}
|
|
73
|
-
if (!studio_protocol_1.StudioProtocolInternals.isValidPublicLicenseKey(parsedRequest.
|
|
65
|
+
if (!studio_protocol_1.StudioProtocolInternals.isValidPublicLicenseKey(parsedRequest.licenseKey)) {
|
|
74
66
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
75
67
|
code: 'invalid-license-key',
|
|
76
68
|
message: 'The license key is not a valid public Remotion license key.',
|
|
@@ -83,7 +75,7 @@ const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, live
|
|
|
83
75
|
now: Date.now(),
|
|
84
76
|
origin: requestOrigin,
|
|
85
77
|
purpose: 'set-license-key',
|
|
86
|
-
targetId: parsedRequest.
|
|
78
|
+
targetId: parsedRequest.targetId,
|
|
87
79
|
});
|
|
88
80
|
if (target === null) {
|
|
89
81
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
@@ -105,7 +97,7 @@ const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, live
|
|
|
105
97
|
}
|
|
106
98
|
const delivered = liveEventsServer.sendEventToClientId(target.clientId, {
|
|
107
99
|
type: 'license-key-install-request',
|
|
108
|
-
licenseKey: parsedRequest.
|
|
100
|
+
licenseKey: parsedRequest.licenseKey,
|
|
109
101
|
});
|
|
110
102
|
if (!delivered) {
|
|
111
103
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
@@ -257,18 +257,10 @@ function popUndo() {
|
|
|
257
257
|
return [
|
|
258
258
|
{
|
|
259
259
|
absolutePath: snapshot.filePath,
|
|
260
|
-
remappings: snapshot.nodePathRemappings.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return [
|
|
265
|
-
{
|
|
266
|
-
oldNodePath: remapping.newNodePath,
|
|
267
|
-
newNodePath: remapping.oldNodePath,
|
|
268
|
-
},
|
|
269
|
-
];
|
|
270
|
-
}),
|
|
271
|
-
restoredNodePaths: snapshot.nodePathRemappings.flatMap((remapping) => remapping.newNodePath === null ? [remapping.oldNodePath] : []),
|
|
260
|
+
remappings: snapshot.nodePathRemappings.map((remapping) => ({
|
|
261
|
+
oldNodePath: remapping.newNodePath,
|
|
262
|
+
newNodePath: remapping.oldNodePath,
|
|
263
|
+
})),
|
|
272
264
|
},
|
|
273
265
|
];
|
|
274
266
|
});
|
|
@@ -339,7 +331,6 @@ function popRedo() {
|
|
|
339
331
|
{
|
|
340
332
|
absolutePath: snapshot.filePath,
|
|
341
333
|
remappings: snapshot.nodePathRemappings,
|
|
342
|
-
restoredNodePaths: [],
|
|
343
334
|
},
|
|
344
335
|
];
|
|
345
336
|
});
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/studio-server",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.520",
|
|
7
7
|
"description": "Run a Remotion Studio with a server backend",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@remotion/studio-protocol": "4.0.
|
|
26
|
+
"@remotion/studio-protocol": "4.0.520",
|
|
27
27
|
"@babel/types": "7.24.0",
|
|
28
28
|
"@babel/parser": "7.24.1",
|
|
29
29
|
"@svgr/core": "8.1.0",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"semver": "7.5.3",
|
|
33
33
|
"zod": "4.4.3",
|
|
34
34
|
"prettier": "3.8.1",
|
|
35
|
-
"remotion": "4.0.
|
|
35
|
+
"remotion": "4.0.520",
|
|
36
36
|
"recast": "0.23.21",
|
|
37
|
-
"@remotion/bundler": "4.0.
|
|
38
|
-
"@remotion/renderer": "4.0.
|
|
39
|
-
"@remotion/studio-codemods": "4.0.
|
|
40
|
-
"@remotion/studio-shared": "4.0.
|
|
37
|
+
"@remotion/bundler": "4.0.520",
|
|
38
|
+
"@remotion/renderer": "4.0.520",
|
|
39
|
+
"@remotion/studio-codemods": "4.0.520",
|
|
40
|
+
"@remotion/studio-shared": "4.0.520",
|
|
41
41
|
"memfs": "3.4.3",
|
|
42
42
|
"open": "8.4.2"
|
|
43
43
|
},
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"ast-types": "0.16.1",
|
|
46
46
|
"react": "19.2.3",
|
|
47
47
|
"@types/semver": "7.5.3",
|
|
48
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
48
|
+
"@remotion/eslint-config-internal": "4.0.520",
|
|
49
49
|
"eslint": "9.19.0",
|
|
50
50
|
"@types/node": "20.12.14",
|
|
51
51
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|