@remotion/studio-server 4.0.522 → 4.0.524
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 +1 -1
- package/dist/canvas-capture/generate-canvas-capture-composition.js +77 -12
- package/dist/codemods/apply-codemod-to-file.js +8 -1
- package/dist/preview-server/api-routes.d.ts +1 -1
- package/dist/preview-server/api-routes.js +0 -2
- package/dist/preview-server/routes/apply-codemod.js +2 -3
- package/dist/preview-server/routes/delete-jsx-node.js +1 -1
- package/dist/preview-server/routes/duplicate-jsx-node.js +1 -1
- package/dist/preview-server/routes/element-install-plan.d.ts +1 -2
- package/dist/preview-server/routes/element-install-plan.js +7 -9
- package/dist/preview-server/routes/insert-element.js +37 -20
- package/dist/preview-server/routes/insert-jsx-element.js +7 -1
- package/dist/preview-server/routes/install-dependency.d.ts +16 -2
- package/dist/preview-server/routes/install-dependency.js +16 -2
- package/dist/preview-server/routes/reorder-sequence.js +1 -1
- package/dist/preview-server/routes/split-jsx-sequence.js +1 -1
- package/dist/preview-server/routes/split-video-from-audio.js +1 -1
- package/dist/preview-server/routes/update-config.js +6 -0
- package/dist/preview-server/sequence-node-path-mutation.d.ts +5 -1
- package/dist/preview-server/sequence-node-path-mutation.js +2 -1
- package/dist/preview-server/start-server.js +17 -0
- package/dist/preview-server/studio-protocol/handle-discovery.js +1 -1
- package/dist/preview-server/studio-protocol/handle-element-library.js +1 -1
- package/dist/preview-server/studio-protocol/handle-install.js +4 -3
- package/dist/preview-server/studio-protocol/handle-license-key.js +1 -1
- package/dist/preview-server/studio-protocol/origin-policy.d.ts +1 -1
- package/dist/preview-server/studio-protocol/origin-policy.js +13 -6
- package/dist/preview-server/undo-stack.js +2 -2
- package/dist/routes.d.ts +2 -1
- package/dist/routes.js +19 -1
- package/package.json +8 -8
|
@@ -1,7 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.generateCanvasCaptureComposition = void 0;
|
|
4
|
-
const
|
|
37
|
+
const recast = __importStar(require("recast"));
|
|
5
38
|
const customCursorRegex = /^\s*url\(/;
|
|
6
39
|
const collapseMouseMovementsByFrame = ({ data, keyframeFps, }) => {
|
|
7
40
|
const movements = [];
|
|
@@ -30,7 +63,39 @@ const getCursorName = (cursor) => {
|
|
|
30
63
|
}
|
|
31
64
|
return ((_a = cursor.split(',').at(-1)) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase()) || 'default';
|
|
32
65
|
};
|
|
33
|
-
const serialize = (value) =>
|
|
66
|
+
const serialize = (value) => {
|
|
67
|
+
if (typeof value === 'string') {
|
|
68
|
+
return recast.prettyPrint(recast.types.builders.stringLiteral(value), {
|
|
69
|
+
quote: 'single',
|
|
70
|
+
}).code;
|
|
71
|
+
}
|
|
72
|
+
return JSON.stringify(value);
|
|
73
|
+
};
|
|
74
|
+
const serializeArray = (values, indentation) => {
|
|
75
|
+
const items = values.map(serialize);
|
|
76
|
+
const inline = `[${items.join(', ')}]`;
|
|
77
|
+
if (indentation * 2 + inline.length + 1 <= 80) {
|
|
78
|
+
return inline;
|
|
79
|
+
}
|
|
80
|
+
const lines = [];
|
|
81
|
+
const numeric = values.every((value) => typeof value === 'number');
|
|
82
|
+
for (const item of items) {
|
|
83
|
+
const previous = lines.at(-1);
|
|
84
|
+
if (numeric &&
|
|
85
|
+
previous &&
|
|
86
|
+
(indentation + 1) * 2 + previous.length + item.length + 2 <= 80) {
|
|
87
|
+
lines[lines.length - 1] = `${previous} ${item},`;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lines.push(`${item},`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return [
|
|
94
|
+
'[',
|
|
95
|
+
...lines.map((line) => `${'\t'.repeat(indentation + 1)}${line}`),
|
|
96
|
+
`${'\t'.repeat(indentation)}]`,
|
|
97
|
+
].join('\n');
|
|
98
|
+
};
|
|
34
99
|
const generateCanvasCaptureComposition = ({ componentName, compositionId, data, durationInFrames, fps, height, keyframeFps, videoFileName, videoHeight, videoWidth, width, }) => {
|
|
35
100
|
var _a;
|
|
36
101
|
const movements = collapseMouseMovementsByFrame({ data, keyframeFps });
|
|
@@ -79,11 +144,11 @@ const generateCanvasCaptureComposition = ({ componentName, compositionId, data,
|
|
|
79
144
|
}, []);
|
|
80
145
|
const customCursor = (_a = movements.find((movement) => customCursorRegex.test(movement.cursor))) === null || _a === void 0 ? void 0 : _a.cursor;
|
|
81
146
|
const cursorProp = cursorKeyframes.length === 1
|
|
82
|
-
? `cursor
|
|
147
|
+
? `cursor={${serialize(cursorKeyframes[0].value)}}`
|
|
83
148
|
: `cursor={interpolate(
|
|
84
149
|
frame,
|
|
85
|
-
${
|
|
86
|
-
${
|
|
150
|
+
${serializeArray(cursorKeyframes.map((keyframe) => keyframe.frame), 5)},
|
|
151
|
+
${serializeArray(cursorKeyframes.map((keyframe) => keyframe.value), 5)},
|
|
87
152
|
{
|
|
88
153
|
easing: Easing.step1,
|
|
89
154
|
extrapolateLeft: 'clamp',
|
|
@@ -94,8 +159,8 @@ const generateCanvasCaptureComposition = ({ componentName, compositionId, data,
|
|
|
94
159
|
? serialize(scaleKeyframes[0].value)
|
|
95
160
|
: `interpolate(
|
|
96
161
|
frame,
|
|
97
|
-
${
|
|
98
|
-
${
|
|
162
|
+
${serializeArray(scaleKeyframes.map((keyframe) => keyframe.frame), 6)},
|
|
163
|
+
${serializeArray(scaleKeyframes.map((keyframe) => keyframe.value), 6)},
|
|
99
164
|
{
|
|
100
165
|
easing: Easing.step1,
|
|
101
166
|
extrapolateLeft: 'clamp',
|
|
@@ -106,8 +171,8 @@ const generateCanvasCaptureComposition = ({ componentName, compositionId, data,
|
|
|
106
171
|
? serialize(positionKeyframes[0].value)
|
|
107
172
|
: `interpolate(
|
|
108
173
|
frame,
|
|
109
|
-
${
|
|
110
|
-
${
|
|
174
|
+
${serializeArray(positionKeyframes.map((keyframe) => keyframe.frame), 6)},
|
|
175
|
+
${serializeArray(positionKeyframes.map((keyframe) => keyframe.value), 6)},
|
|
111
176
|
{
|
|
112
177
|
extrapolateLeft: 'clamp',
|
|
113
178
|
extrapolateRight: 'clamp',
|
|
@@ -116,7 +181,7 @@ const generateCanvasCaptureComposition = ({ componentName, compositionId, data,
|
|
|
116
181
|
const previewComponentName = componentName.endsWith('Composition')
|
|
117
182
|
? `${componentName.slice(0, -'Composition'.length)}Preview`
|
|
118
183
|
: `${componentName}Preview`;
|
|
119
|
-
return
|
|
184
|
+
return `import {MacOSCursor} from '@remotion/mac-cursors';
|
|
120
185
|
import {Video} from '@remotion/media';
|
|
121
186
|
import {
|
|
122
187
|
AbsoluteFill,
|
|
@@ -160,7 +225,7 @@ ${customCursor === undefined ? '' : `\t\t\t\tcustomCursor={${serialize(customCur
|
|
|
160
225
|
export const ${componentName} = () => {
|
|
161
226
|
return (
|
|
162
227
|
<Composition
|
|
163
|
-
id
|
|
228
|
+
id={${serialize(compositionId)}}
|
|
164
229
|
component={${previewComponentName}}
|
|
165
230
|
width={${width}}
|
|
166
231
|
height={${height}}
|
|
@@ -169,6 +234,6 @@ export const ${componentName} = () => {
|
|
|
169
234
|
/>
|
|
170
235
|
);
|
|
171
236
|
};
|
|
172
|
-
|
|
237
|
+
`;
|
|
173
238
|
};
|
|
174
239
|
exports.generateCanvasCaptureComposition = generateCanvasCaptureComposition;
|
|
@@ -27,6 +27,13 @@ const applyCodemodToFile = async ({ filePath, codeMod, }) => {
|
|
|
27
27
|
codeMod,
|
|
28
28
|
input,
|
|
29
29
|
});
|
|
30
|
-
|
|
30
|
+
if (codeMod.type === 'new-composition' ||
|
|
31
|
+
codeMod.type === 'duplicate-composition' ||
|
|
32
|
+
codeMod.type === 'rename-composition' ||
|
|
33
|
+
codeMod.type === 'delete-composition') {
|
|
34
|
+
return newContents;
|
|
35
|
+
}
|
|
36
|
+
const formatted = await (0, duplicate_composition_1.formatOutput)(newContents);
|
|
37
|
+
return formatted;
|
|
31
38
|
};
|
|
32
39
|
exports.applyCodemodToFile = applyCodemodToFile;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ApiRoutes } from '@remotion/studio-shared';
|
|
2
2
|
import type { ApiHandler } from './api-types';
|
|
3
|
-
type StandardApiRoute = Exclude<keyof ApiRoutes, '/api/update-config'>;
|
|
3
|
+
type StandardApiRoute = Exclude<keyof ApiRoutes, '/api/install-package' | '/api/update-config'>;
|
|
4
4
|
export declare const allApiRoutes: {
|
|
5
5
|
[key in StandardApiRoute]: ApiHandler<ApiRoutes[key]['Request'], ApiRoutes[key]['Response']>;
|
|
6
6
|
};
|
|
@@ -25,7 +25,6 @@ const duplicate_jsx_node_1 = require("./routes/duplicate-jsx-node");
|
|
|
25
25
|
const find_in_file_1 = require("./routes/find-in-file");
|
|
26
26
|
const insert_element_1 = require("./routes/insert-element");
|
|
27
27
|
const insert_jsx_element_1 = require("./routes/insert-jsx-element");
|
|
28
|
-
const install_dependency_1 = require("./routes/install-dependency");
|
|
29
28
|
const log_studio_error_1 = require("./routes/log-studio-error");
|
|
30
29
|
const move_keyframes_1 = require("./routes/move-keyframes");
|
|
31
30
|
const open_in_editor_1 = require("./routes/open-in-editor");
|
|
@@ -120,7 +119,6 @@ exports.allApiRoutes = {
|
|
|
120
119
|
'/api/restart-studio': restart_studio_1.handleRestartStudio,
|
|
121
120
|
'/api/default-coding-agent-info': default_coding_agent_1.getDefaultCodingAgentInfoHandler,
|
|
122
121
|
'/api/default-editor-info': default_editor_1.getDefaultEditorInfoHandler,
|
|
123
|
-
'/api/install-package': install_dependency_1.handleInstallPackage,
|
|
124
122
|
'/api/insert-jsx-element': insert_jsx_element_1.insertJsxElementHandler,
|
|
125
123
|
'/api/insert-element': insert_element_1.insertElementHandler,
|
|
126
124
|
'/api/prepare-element-install': prepare_element_install_1.prepareElementInstallHandler,
|
|
@@ -10,7 +10,6 @@ const renderer_1 = require("@remotion/renderer");
|
|
|
10
10
|
const studio_codemods_1 = require("@remotion/studio-codemods");
|
|
11
11
|
const generate_canvas_capture_composition_1 = require("../../canvas-capture/generate-canvas-capture-composition");
|
|
12
12
|
const apply_codemod_to_file_1 = require("../../codemods/apply-codemod-to-file");
|
|
13
|
-
const duplicate_composition_1 = require("../../codemods/duplicate-composition");
|
|
14
13
|
const file_watcher_1 = require("../../file-watcher");
|
|
15
14
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
16
15
|
const project_info_1 = require("../project-info");
|
|
@@ -33,12 +32,12 @@ const formatNewCompositionFile = (codemod) => {
|
|
|
33
32
|
width: codemod.newWidth,
|
|
34
33
|
});
|
|
35
34
|
}
|
|
36
|
-
return
|
|
35
|
+
return `import React from 'react';
|
|
37
36
|
|
|
38
37
|
export const ${codemod.componentName}: React.FC = () => {
|
|
39
38
|
return null;
|
|
40
39
|
};
|
|
41
|
-
|
|
40
|
+
`;
|
|
42
41
|
};
|
|
43
42
|
const getFolderPath = (parentName, folderName) => {
|
|
44
43
|
return parentName ? `${parentName}/${folderName}` : folderName;
|
|
@@ -65,7 +65,7 @@ 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
|
-
})));
|
|
68
|
+
})), null);
|
|
69
69
|
for (const update of updates) {
|
|
70
70
|
const deletedNodeDescription = getDeletedNodeDescription(update.nodeLabels);
|
|
71
71
|
(0, undo_stack_1.pushToUndoStack)({
|
|
@@ -50,7 +50,7 @@ const duplicateJsxNodeHandler = ({ input: { nodes }, remotionRoot, logLevel }) =
|
|
|
50
50
|
const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(updates.map((update) => ({
|
|
51
51
|
absolutePath: update.absolutePath,
|
|
52
52
|
remappings: update.nodePathRemappings,
|
|
53
|
-
})));
|
|
53
|
+
})), null);
|
|
54
54
|
const duplicatedNodeDescription = nodes.length === 1
|
|
55
55
|
? updates[0].nodeLabels[0]
|
|
56
56
|
: `${nodes.length} JSX nodes`;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ElementInstallExpectedFileState, PrepareElementInstallRequest } from '@remotion/studio-shared';
|
|
2
|
-
export declare const normalizeElementSourceForComparison: (source: string) => string;
|
|
3
2
|
export declare const getElementSourceHash: (source: string) => string;
|
|
4
3
|
export declare const validateElementInstallPosition: (position: import("@remotion/studio-shared").InsertableCompositionElementPosition | null) => void;
|
|
5
4
|
export declare const validateElementForInstallation: (element: import("@remotion/studio-shared").InstallableElement) => void;
|
|
@@ -7,7 +6,7 @@ export declare const makeRelativeElementImportPath: ({ fromFile, toFile, }: {
|
|
|
7
6
|
fromFile: string;
|
|
8
7
|
toFile: string;
|
|
9
8
|
}) => string;
|
|
10
|
-
export declare const getElementInstallPlan: ({ destination, element, entryPoint, remotionRoot, }: PrepareElementInstallRequest & {
|
|
9
|
+
export declare const getElementInstallPlan: ({ destination, element, installationName, entryPoint, remotionRoot, }: PrepareElementInstallRequest & {
|
|
11
10
|
entryPoint: string;
|
|
12
11
|
remotionRoot: string;
|
|
13
12
|
}) => Promise<{
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getElementInstallPlan = exports.makeRelativeElementImportPath = exports.validateElementForInstallation = exports.validateElementInstallPosition = exports.getElementSourceHash =
|
|
6
|
+
exports.getElementInstallPlan = exports.makeRelativeElementImportPath = exports.validateElementForInstallation = exports.validateElementInstallPosition = exports.getElementSourceHash = void 0;
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
8
|
const node_fs_1 = require("node:fs");
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -11,10 +11,6 @@ const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
|
11
11
|
const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
|
|
12
12
|
const project_info_1 = require("../project-info");
|
|
13
13
|
const safe_element_install_path_1 = require("./safe-element-install-path");
|
|
14
|
-
const normalizeElementSourceForComparison = (source) => {
|
|
15
|
-
return source.replace(/\r\n/g, '\n').trim();
|
|
16
|
-
};
|
|
17
|
-
exports.normalizeElementSourceForComparison = normalizeElementSourceForComparison;
|
|
18
14
|
const getElementSourceHash = (source) => {
|
|
19
15
|
return (0, node_crypto_1.createHash)('sha256').update(source).digest('hex');
|
|
20
16
|
};
|
|
@@ -75,7 +71,7 @@ const getExpectedFileState = (existingSource) => {
|
|
|
75
71
|
sourceHash: (0, exports.getElementSourceHash)(existingSource),
|
|
76
72
|
};
|
|
77
73
|
};
|
|
78
|
-
const getElementInstallPlan = async ({ destination, element, entryPoint, remotionRoot, }) => {
|
|
74
|
+
const getElementInstallPlan = async ({ destination, element, installationName, entryPoint, remotionRoot, }) => {
|
|
79
75
|
var _a;
|
|
80
76
|
(0, exports.validateElementForInstallation)(element);
|
|
81
77
|
const componentName = studio_protocol_1.StudioProtocolInternals.getElementComponentNameFromSourceCode(element.sourceCode);
|
|
@@ -92,9 +88,11 @@ const getElementInstallPlan = async ({ destination, element, entryPoint, remotio
|
|
|
92
88
|
if (location !== null && !location.canAddSequence) {
|
|
93
89
|
throw new Error('Cannot insert Element into this composition component');
|
|
94
90
|
}
|
|
95
|
-
const derivedElementFileName = studio_protocol_1.StudioProtocolInternals.makeElementFileNameFromSlug(element.slug);
|
|
96
|
-
if (derivedElementFileName === null
|
|
97
|
-
|
|
91
|
+
const derivedElementFileName = studio_protocol_1.StudioProtocolInternals.makeElementFileNameFromSlug(installationName !== null && installationName !== void 0 ? installationName : element.slug);
|
|
92
|
+
if (derivedElementFileName === null ||
|
|
93
|
+
(typeof installationName === 'string' &&
|
|
94
|
+
derivedElementFileName !== `${installationName}.element.tsx`)) {
|
|
95
|
+
throw new Error('Use a lowercase installation name with letters, numbers and hyphens, without a file extension.');
|
|
98
96
|
}
|
|
99
97
|
const destinationCompositionFile = destination.compositionFile;
|
|
100
98
|
const destinationCompositionFileName = destinationCompositionFile === null
|
|
@@ -21,7 +21,9 @@ const hasExpectedFileState = ({ expected, actual, }) => {
|
|
|
21
21
|
}
|
|
22
22
|
return actual.sourceHash === expected.sourceHash;
|
|
23
23
|
};
|
|
24
|
-
const insertElementHandler = ({ input: { compositionFile, compositionId, element, expectedFileState, from, position, overwriteExisting, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
24
|
+
const insertElementHandler = ({ input: { compositionFile, compositionId, element, installationName, expectedFileState, from, position, overwriteExisting, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
25
|
+
var _a;
|
|
26
|
+
var _b;
|
|
25
27
|
try {
|
|
26
28
|
(0, element_install_plan_1.validateElementInstallPosition)(position);
|
|
27
29
|
if (from !== null &&
|
|
@@ -32,8 +34,24 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
32
34
|
? 'wrapped'
|
|
33
35
|
: element.installationMode;
|
|
34
36
|
const componentOwnsSequence = installationMode === 'component-owned-sequence';
|
|
37
|
+
if (componentOwnsSequence &&
|
|
38
|
+
element.initialProps !== null &&
|
|
39
|
+
['from', 'durationInFrames', 'name'].some((prop) => {
|
|
40
|
+
var _a;
|
|
41
|
+
return Object.hasOwn((_a = element.initialProps) !== null && _a !== void 0 ? _a : {}, prop);
|
|
42
|
+
})) {
|
|
43
|
+
throw new Error('Component-owned Element initial props must not override from, durationInFrames, or name');
|
|
44
|
+
}
|
|
45
|
+
if (componentOwnsSequence &&
|
|
46
|
+
((_a = element.initialProps) === null || _a === void 0 ? void 0 : _a.style) !== undefined &&
|
|
47
|
+
(element.initialProps.style === null ||
|
|
48
|
+
typeof element.initialProps.style !== 'object' ||
|
|
49
|
+
Array.isArray(element.initialProps.style))) {
|
|
50
|
+
throw new Error('Component-owned Element initial style must be an object');
|
|
51
|
+
}
|
|
35
52
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
|
|
36
53
|
const plan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
54
|
+
installationName,
|
|
37
55
|
destination: {
|
|
38
56
|
type: 'current-composition',
|
|
39
57
|
compositionFile,
|
|
@@ -63,11 +81,8 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
63
81
|
throw new Error('Element source changed during installation');
|
|
64
82
|
}
|
|
65
83
|
const elementSourcesDiffer = plan.existingElementSource !== null &&
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (elementSourcesDiffer &&
|
|
69
|
-
!overwriteExisting &&
|
|
70
|
-
plan.existingElementSource !== null) {
|
|
84
|
+
plan.existingElementSource !== element.sourceCode;
|
|
85
|
+
if (!overwriteExisting && plan.existingElementSource !== null) {
|
|
71
86
|
return {
|
|
72
87
|
success: false,
|
|
73
88
|
type: 'file-conflict',
|
|
@@ -88,19 +103,20 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
88
103
|
componentName: plan.componentName,
|
|
89
104
|
importName: plan.componentName,
|
|
90
105
|
importPath: plan.importPath,
|
|
91
|
-
props:
|
|
92
|
-
? [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
106
|
+
props: [
|
|
107
|
+
...Object.entries((_b = element.initialProps) !== null && _b !== void 0 ? _b : {}).map(([name, value]) => ({ name, value })),
|
|
108
|
+
...(componentOwnsSequence && element.durationInFrames !== null
|
|
109
|
+
? [
|
|
110
|
+
{
|
|
111
|
+
name: 'durationInFrames',
|
|
112
|
+
value: element.durationInFrames,
|
|
113
|
+
},
|
|
114
|
+
]
|
|
115
|
+
: []),
|
|
116
|
+
...(componentOwnsSequence
|
|
117
|
+
? [{ name: 'name', value: element.displayName }]
|
|
118
|
+
: []),
|
|
119
|
+
],
|
|
104
120
|
position: componentOwnsSequence ? position : null,
|
|
105
121
|
},
|
|
106
122
|
from: componentOwnsSequence ? from : null,
|
|
@@ -116,6 +132,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
116
132
|
},
|
|
117
133
|
});
|
|
118
134
|
const finalPlan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
135
|
+
installationName,
|
|
119
136
|
destination: {
|
|
120
137
|
type: 'current-composition',
|
|
121
138
|
compositionFile,
|
|
@@ -140,7 +157,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
140
157
|
absolutePath: inserted.fileName,
|
|
141
158
|
remappings: inserted.nodePathRemappings,
|
|
142
159
|
},
|
|
143
|
-
]);
|
|
160
|
+
], null);
|
|
144
161
|
(0, undo_stack_1.pushTransactionToUndoStack)({
|
|
145
162
|
snapshots: [
|
|
146
163
|
...(shouldWriteElementFile
|
|
@@ -171,7 +171,13 @@ const insertJsxElementHandler = ({ input: { compositionFile, compositionId, elem
|
|
|
171
171
|
absolutePath: fileName,
|
|
172
172
|
remappings: nodePathRemappings,
|
|
173
173
|
},
|
|
174
|
-
]
|
|
174
|
+
], insertedNodePath === null
|
|
175
|
+
? null
|
|
176
|
+
: {
|
|
177
|
+
absolutePath: fileName,
|
|
178
|
+
compositionId,
|
|
179
|
+
nodePath: insertedNodePath,
|
|
180
|
+
});
|
|
175
181
|
if (insertedNodePath === null) {
|
|
176
182
|
renderer_1.RenderInternals.Log.warn({ indent: false, logLevel }, 'Could not determine the inserted JSX element node path. Skipping automatic selection.');
|
|
177
183
|
}
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { type InstallPackageRequest, type InstallPackageResponse, type PackageInstallSpec } from '@remotion/studio-shared';
|
|
2
|
-
import type { ApiHandler } from '../api-types';
|
|
3
2
|
export declare const getPackageInstallSpec: (dependency: PackageInstallSpec) => string;
|
|
4
|
-
export declare const handleInstallPackage:
|
|
3
|
+
export declare const handleInstallPackage: ({ logLevel, remotionRoot, input: { dependencies }, invalidateBundle, }: {
|
|
4
|
+
input: InstallPackageRequest;
|
|
5
|
+
entryPoint: string;
|
|
6
|
+
remotionRoot: string;
|
|
7
|
+
request: import("http").IncomingMessage;
|
|
8
|
+
response: import("http").ServerResponse<import("http").IncomingMessage>;
|
|
9
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
10
|
+
methods: import("../api-types").QueueMethods;
|
|
11
|
+
publicDir: string;
|
|
12
|
+
binariesDirectory: string | null;
|
|
13
|
+
configFile: string | null;
|
|
14
|
+
getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
|
|
15
|
+
getDefaultEditor: () => import("@remotion/renderer").DefaultEditor | null;
|
|
16
|
+
} & {
|
|
17
|
+
readonly invalidateBundle: () => Promise<void>;
|
|
18
|
+
}) => Promise<InstallPackageResponse>;
|
|
@@ -22,7 +22,7 @@ const getPackageInstallSpec = (dependency) => {
|
|
|
22
22
|
return extraVersion === null ? name : `${name}@${extraVersion}`;
|
|
23
23
|
};
|
|
24
24
|
exports.getPackageInstallSpec = getPackageInstallSpec;
|
|
25
|
-
const handleInstallPackage = async ({ logLevel, remotionRoot, input: { dependencies } }) => {
|
|
25
|
+
const handleInstallPackage = async ({ logLevel, remotionRoot, input: { dependencies }, invalidateBundle, }) => {
|
|
26
26
|
for (const dependency of dependencies) {
|
|
27
27
|
if (!(0, studio_shared_1.isValidPackageName)(dependency.name)) {
|
|
28
28
|
return Promise.reject(new Error(`Package name ${JSON.stringify(dependency.name)} is invalid.`));
|
|
@@ -41,12 +41,24 @@ const handleInstallPackage = async ({ logLevel, remotionRoot, input: { dependenc
|
|
|
41
41
|
if (manager === 'unknown') {
|
|
42
42
|
throw new Error(`No lockfile was found in your project (one of ${get_package_manager_1.lockFilePaths.map((p) => p.path).join(', ')}). Install dependencies using your favorite manager!`);
|
|
43
43
|
}
|
|
44
|
+
const additionalArgs = ['--ignore-scripts'];
|
|
45
|
+
if (manager.manager === 'yarn') {
|
|
46
|
+
const version = (0, node_child_process_1.execFileSync)('yarn', ['--version'], {
|
|
47
|
+
...(0, package_manager_spawn_options_1.getPackageManagerSpawnOptions)(),
|
|
48
|
+
cwd: remotionRoot,
|
|
49
|
+
encoding: 'utf8',
|
|
50
|
+
timeout: 10000,
|
|
51
|
+
}).trim();
|
|
52
|
+
if (!/^1\./.test(version)) {
|
|
53
|
+
additionalArgs[0] = '--mode=skip-build';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
44
56
|
const packagesWithVersions = dependencies.map(exports.getPackageInstallSpec);
|
|
45
57
|
const command = (0, install_command_1.getInstallCommand)({
|
|
46
58
|
manager: manager.manager,
|
|
47
59
|
packages: packagesWithVersions,
|
|
48
60
|
version: '',
|
|
49
|
-
additionalArgs
|
|
61
|
+
additionalArgs,
|
|
50
62
|
});
|
|
51
63
|
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray(`╭─ ${manager.manager} ${command.join(' ')}`));
|
|
52
64
|
const time = Date.now();
|
|
@@ -54,6 +66,7 @@ const handleInstallPackage = async ({ logLevel, remotionRoot, input: { dependenc
|
|
|
54
66
|
await new Promise((resolve, reject) => {
|
|
55
67
|
const cmd = (0, node_child_process_1.spawn)(manager.manager, command, {
|
|
56
68
|
...(0, package_manager_spawn_options_1.getPackageManagerSpawnOptions)(),
|
|
69
|
+
cwd: remotionRoot,
|
|
57
70
|
env: {
|
|
58
71
|
...process.env,
|
|
59
72
|
YARN_ENABLE_SCRIPTS: 'false',
|
|
@@ -70,6 +83,7 @@ const handleInstallPackage = async ({ logLevel, remotionRoot, input: { dependenc
|
|
|
70
83
|
? resolve()
|
|
71
84
|
: reject(new Error(`Command exited with code ${code} and signal ${signal}`)));
|
|
72
85
|
});
|
|
86
|
+
await invalidateBundle();
|
|
73
87
|
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray('╰─ '), `Done in ${Date.now() - time}ms`);
|
|
74
88
|
return {};
|
|
75
89
|
}
|
|
@@ -238,6 +238,12 @@ const updateConfigHandler = async ({ input, configFile, getStudioRuntimeConfig,
|
|
|
238
238
|
if (update.type === 'delete') {
|
|
239
239
|
continue;
|
|
240
240
|
}
|
|
241
|
+
if (update.setter === 'setKeyboardShortcuts') {
|
|
242
|
+
const keyboardShortcutsError = (0, studio_shared_1.validateStudioKeyboardShortcuts)(update.value);
|
|
243
|
+
if (keyboardShortcutsError !== null) {
|
|
244
|
+
return { success: false, reason: keyboardShortcutsError };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
241
247
|
if (update.setter === 'setDefaultCodingAgent' &&
|
|
242
248
|
(typeof update.value !== 'string' ||
|
|
243
249
|
!renderer_1.defaultCodingAgentIds.includes(update.value))) {
|
|
@@ -2,4 +2,8 @@ import type { SequenceNodePathMutation, SequenceNodePathRemapping } from '@remot
|
|
|
2
2
|
export declare const broadcastSequenceNodePathMutation: (files: {
|
|
3
3
|
absolutePath: string;
|
|
4
4
|
remappings: SequenceNodePathRemapping[];
|
|
5
|
-
}[]
|
|
5
|
+
}[], timelineSelection: {
|
|
6
|
+
compositionId: string;
|
|
7
|
+
absolutePath: string;
|
|
8
|
+
nodePath: import("remotion").SequenceNodePath;
|
|
9
|
+
} | null) => SequenceNodePathMutation;
|
|
@@ -5,11 +5,12 @@ const node_crypto_1 = require("node:crypto");
|
|
|
5
5
|
const live_events_1 = require("./live-events");
|
|
6
6
|
const mutationSessionId = (0, node_crypto_1.randomUUID)();
|
|
7
7
|
let mutationCounter = 0;
|
|
8
|
-
const broadcastSequenceNodePathMutation = (files) => {
|
|
8
|
+
const broadcastSequenceNodePathMutation = (files, timelineSelection) => {
|
|
9
9
|
var _a;
|
|
10
10
|
mutationCounter++;
|
|
11
11
|
const mutation = {
|
|
12
12
|
mutationId: `${mutationSessionId}:${mutationCounter}`,
|
|
13
|
+
timelineSelection,
|
|
13
14
|
files,
|
|
14
15
|
};
|
|
15
16
|
(_a = (0, live_events_1.getLiveEventsListener)()) === null || _a === void 0 ? void 0 : _a.sendEventToClient({
|
|
@@ -140,6 +140,22 @@ const startServer = async (options) => {
|
|
|
140
140
|
}
|
|
141
141
|
(0, watch_ignore_next_change_1.setWatchIgnoreNextChangePlugin)(watchIgnorePlugin);
|
|
142
142
|
const wdmMiddleware = (0, dev_middleware_1.wdm)(compiler, options.logLevel);
|
|
143
|
+
const invalidateBundle = () => {
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
const watching = compiler === null || compiler === void 0 ? void 0 : compiler.watching;
|
|
146
|
+
if (!watching) {
|
|
147
|
+
reject(new Error('The Studio bundle is not being watched.'));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
watching.invalidate((error) => {
|
|
151
|
+
if (error) {
|
|
152
|
+
reject(error);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
resolve();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
};
|
|
143
159
|
const liveEventsServer = (0, live_events_1.makeLiveEventsRouter)(options.logLevel, () => {
|
|
144
160
|
const undoStack = (0, undo_stack_1.getUndoStack)();
|
|
145
161
|
const redoStack = (0, undo_stack_1.getRedoStack)();
|
|
@@ -196,6 +212,7 @@ const startServer = async (options) => {
|
|
|
196
212
|
getDefaultCodingAgent: options.getDefaultCodingAgent,
|
|
197
213
|
getDefaultEditor: options.getDefaultEditor,
|
|
198
214
|
configFile: options.configFile,
|
|
215
|
+
invalidateBundle,
|
|
199
216
|
});
|
|
200
217
|
})
|
|
201
218
|
.catch((err) => {
|
|
@@ -43,7 +43,7 @@ const getProject = ({ gitSource, remotionRoot, }) => (0, studio_shared_1.getProj
|
|
|
43
43
|
});
|
|
44
44
|
const handleStudioProtocolDiscovery = ({ gitSource, liveEventsServer, remotionRoot, request, response, }) => {
|
|
45
45
|
(0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
|
|
46
|
-
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request
|
|
46
|
+
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request);
|
|
47
47
|
if (requestOrigin === null) {
|
|
48
48
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
49
49
|
code: 'unsupported-origin',
|
|
@@ -11,7 +11,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
|
|
|
11
11
|
var _a;
|
|
12
12
|
var _b;
|
|
13
13
|
(0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
|
|
14
|
-
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request
|
|
14
|
+
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request);
|
|
15
15
|
if (requestOrigin === null) {
|
|
16
16
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
17
17
|
code: 'unsupported-origin',
|
|
@@ -10,7 +10,7 @@ const protocol_response_1 = require("./protocol-response");
|
|
|
10
10
|
// UTF-8 representation and the protocol envelope while keeping memory bounded.
|
|
11
11
|
const MAX_STUDIO_PROTOCOL_INSTALL_BODY_SIZE = 1000000;
|
|
12
12
|
const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, origin, target, }) => {
|
|
13
|
-
var _a, _b;
|
|
13
|
+
var _a, _b, _c;
|
|
14
14
|
if (target.compositionFile === null || target.compositionId === null) {
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
@@ -23,7 +23,8 @@ const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, orig
|
|
|
23
23
|
element: {
|
|
24
24
|
...element,
|
|
25
25
|
durationInFrames: (_a = element.durationInFrames) !== null && _a !== void 0 ? _a : null,
|
|
26
|
-
|
|
26
|
+
initialProps: (_b = element.initialProps) !== null && _b !== void 0 ? _b : null,
|
|
27
|
+
installationMode: (_c = element.installationMode) !== null && _c !== void 0 ? _c : null,
|
|
27
28
|
},
|
|
28
29
|
from: null,
|
|
29
30
|
position: null,
|
|
@@ -43,7 +44,7 @@ const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, orig
|
|
|
43
44
|
};
|
|
44
45
|
const handleStudioProtocolInstall = async ({ focusStudioTab, liveEventsServer, request, response, }) => {
|
|
45
46
|
(0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
|
|
46
|
-
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request
|
|
47
|
+
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request);
|
|
47
48
|
if (requestOrigin === null) {
|
|
48
49
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
49
50
|
code: 'unsupported-origin',
|
|
@@ -9,7 +9,7 @@ const protocol_response_1 = require("./protocol-response");
|
|
|
9
9
|
const MAX_STUDIO_PROTOCOL_LICENSE_KEY_BODY_SIZE = 4096;
|
|
10
10
|
const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, liveEventsServer, request, response, }) => {
|
|
11
11
|
(0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
|
|
12
|
-
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request
|
|
12
|
+
const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request);
|
|
13
13
|
if (requestOrigin === null) {
|
|
14
14
|
(0, protocol_response_1.writeStudioProtocolError)({
|
|
15
15
|
code: 'unsupported-origin',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
export declare const getAllowedStudioProtocolOrigin: (
|
|
2
|
+
export declare const getAllowedStudioProtocolOrigin: (request: IncomingMessage) => string | null;
|
|
3
3
|
export declare const setStudioProtocolCorsHeaders: ({ request, response, }: {
|
|
4
4
|
readonly request: IncomingMessage;
|
|
5
5
|
readonly response: ServerResponse<IncomingMessage>;
|
|
@@ -3,11 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.handleStudioProtocolOptions = exports.setStudioProtocolCorsHeaders = exports.getAllowedStudioProtocolOrigin = void 0;
|
|
4
4
|
const isLoopbackHttp = (url) => url.protocol === 'http:' &&
|
|
5
5
|
(url.hostname === 'localhost' || url.hostname === '127.0.0.1');
|
|
6
|
-
const getAllowedStudioProtocolOrigin = (
|
|
7
|
-
if (!origin) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
6
|
+
const getAllowedStudioProtocolOrigin = (request) => {
|
|
10
7
|
try {
|
|
8
|
+
const { origin, referer, host } = request.headers;
|
|
9
|
+
if (origin === undefined) {
|
|
10
|
+
// Browsers omit Origin on same-origin GET requests. Only trust a
|
|
11
|
+
// Referer matching this local HTTP Studio, never an arbitrary site.
|
|
12
|
+
const refererUrl = new URL(referer !== null && referer !== void 0 ? referer : '');
|
|
13
|
+
return isLoopbackHttp(refererUrl) &&
|
|
14
|
+
refererUrl.origin === `http://${host}`
|
|
15
|
+
? refererUrl.origin
|
|
16
|
+
: null;
|
|
17
|
+
}
|
|
11
18
|
const url = new URL(origin);
|
|
12
19
|
if (url.protocol !== 'https:' && !isLoopbackHttp(url)) {
|
|
13
20
|
return null;
|
|
@@ -20,7 +27,7 @@ const getAllowedStudioProtocolOrigin = (origin) => {
|
|
|
20
27
|
};
|
|
21
28
|
exports.getAllowedStudioProtocolOrigin = getAllowedStudioProtocolOrigin;
|
|
22
29
|
const setStudioProtocolCorsHeaders = ({ request, response, }) => {
|
|
23
|
-
const origin = (0, exports.getAllowedStudioProtocolOrigin)(request
|
|
30
|
+
const origin = (0, exports.getAllowedStudioProtocolOrigin)(request);
|
|
24
31
|
if (origin === null) {
|
|
25
32
|
return;
|
|
26
33
|
}
|
|
@@ -34,7 +41,7 @@ const setStudioProtocolCorsHeaders = ({ request, response, }) => {
|
|
|
34
41
|
exports.setStudioProtocolCorsHeaders = setStudioProtocolCorsHeaders;
|
|
35
42
|
const handleStudioProtocolOptions = ({ request, response, }) => {
|
|
36
43
|
(0, exports.setStudioProtocolCorsHeaders)({ request, response });
|
|
37
|
-
const origin = (0, exports.getAllowedStudioProtocolOrigin)(request
|
|
44
|
+
const origin = (0, exports.getAllowedStudioProtocolOrigin)(request);
|
|
38
45
|
response.writeHead(origin === null ? 403 : 204);
|
|
39
46
|
response.end();
|
|
40
47
|
return Promise.resolve();
|
|
@@ -264,7 +264,7 @@ function popUndo() {
|
|
|
264
264
|
},
|
|
265
265
|
];
|
|
266
266
|
});
|
|
267
|
-
const nodePathMutation = files.length === 0 ? null : (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(files);
|
|
267
|
+
const nodePathMutation = files.length === 0 ? null : (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(files, null);
|
|
268
268
|
for (const snapshot of entry.snapshots) {
|
|
269
269
|
suppressUndoStackInvalidation(snapshot.filePath);
|
|
270
270
|
if (entry.suppressHmrOnFileRestore) {
|
|
@@ -334,7 +334,7 @@ function popRedo() {
|
|
|
334
334
|
},
|
|
335
335
|
];
|
|
336
336
|
});
|
|
337
|
-
const nodePathMutation = files.length === 0 ? null : (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(files);
|
|
337
|
+
const nodePathMutation = files.length === 0 ? null : (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)(files, null);
|
|
338
338
|
for (const snapshot of snapshotsWithNewContents) {
|
|
339
339
|
suppressUndoStackInvalidation(snapshot.filePath);
|
|
340
340
|
if (entry.suppressHmrOnFileRestore) {
|
package/dist/routes.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { DefaultEditor } from '@remotion/renderer';
|
|
|
3
3
|
import type { GitSource, RenderDefaults, RenderJob, StudioRuntimeConfig } from '@remotion/studio-shared';
|
|
4
4
|
import type { QueueMethods } from './preview-server/api-types';
|
|
5
5
|
import type { LiveEventsServer } from './preview-server/live-events';
|
|
6
|
-
export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash, outputHashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, entryPoint, publicDir, logLevel, getRenderQueue, getRenderDefaults, getNumberOfAudioTags, queueMethods: methods, gitSource, binariesDirectory, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, }: {
|
|
6
|
+
export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash, outputHashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, entryPoint, publicDir, logLevel, getRenderQueue, getRenderDefaults, getNumberOfAudioTags, queueMethods: methods, gitSource, binariesDirectory, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, invalidateBundle, }: {
|
|
7
7
|
staticHash: string;
|
|
8
8
|
staticHashPrefix: string;
|
|
9
9
|
outputHash: string;
|
|
@@ -31,4 +31,5 @@ export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash,
|
|
|
31
31
|
getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
|
|
32
32
|
getDefaultEditor: () => DefaultEditor | null;
|
|
33
33
|
configFile: string | null;
|
|
34
|
+
invalidateBundle: () => Promise<void>;
|
|
34
35
|
}) => Promise<void>;
|
package/dist/routes.js
CHANGED
|
@@ -52,6 +52,7 @@ const get_static_file_fallback_hint_1 = require("./preview-server/get-static-fil
|
|
|
52
52
|
const handler_1 = require("./preview-server/handler");
|
|
53
53
|
const public_folder_1 = require("./preview-server/public-folder");
|
|
54
54
|
const app_icon_1 = require("./preview-server/routes/app-icon");
|
|
55
|
+
const install_dependency_1 = require("./preview-server/routes/install-dependency");
|
|
55
56
|
const open_in_editor_1 = require("./preview-server/routes/open-in-editor");
|
|
56
57
|
const update_config_1 = require("./preview-server/routes/update-config");
|
|
57
58
|
const serve_static_1 = require("./preview-server/serve-static");
|
|
@@ -139,6 +140,7 @@ const handleFallback = async ({ remotionRoot, hash, response, request, getCurren
|
|
|
139
140
|
(0, public_folder_1.fetchFolder)({ publicDir, staticHash: hash });
|
|
140
141
|
const installedDependencies = (0, get_installed_installable_packages_1.getInstalledInstallablePackages)(remotionRoot);
|
|
141
142
|
response.end(bundler_1.BundlerInternals.indexHtml({
|
|
143
|
+
importMap: null,
|
|
142
144
|
staticHash: hash,
|
|
143
145
|
publicPath: '/',
|
|
144
146
|
editorName: displayName,
|
|
@@ -287,7 +289,7 @@ const handleBeep = (_, response) => {
|
|
|
287
289
|
readStream.pipe(response);
|
|
288
290
|
return Promise.resolve();
|
|
289
291
|
};
|
|
290
|
-
const handleRoutes = ({ staticHash, staticHashPrefix, outputHash, outputHashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, entryPoint, publicDir, logLevel, getRenderQueue, getRenderDefaults, getNumberOfAudioTags, queueMethods: methods, gitSource, binariesDirectory, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, }) => {
|
|
292
|
+
const handleRoutes = ({ staticHash, staticHashPrefix, outputHash, outputHashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, entryPoint, publicDir, logLevel, getRenderQueue, getRenderDefaults, getNumberOfAudioTags, queueMethods: methods, gitSource, binariesDirectory, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, invalidateBundle, }) => {
|
|
291
293
|
const url = new URL(request.url, 'http://localhost');
|
|
292
294
|
if (url.pathname === '/api/file-source') {
|
|
293
295
|
return handleFileSource({
|
|
@@ -387,6 +389,22 @@ const handleRoutes = ({ staticHash, staticHashPrefix, outputHash, outputHashPref
|
|
|
387
389
|
getDefaultEditor,
|
|
388
390
|
});
|
|
389
391
|
}
|
|
392
|
+
if (url.pathname === '/api/install-package') {
|
|
393
|
+
return (0, handler_1.handleRequest)({
|
|
394
|
+
remotionRoot,
|
|
395
|
+
entryPoint,
|
|
396
|
+
handler: (params) => (0, install_dependency_1.handleInstallPackage)({ ...params, invalidateBundle }),
|
|
397
|
+
request,
|
|
398
|
+
response,
|
|
399
|
+
logLevel,
|
|
400
|
+
methods,
|
|
401
|
+
binariesDirectory,
|
|
402
|
+
publicDir,
|
|
403
|
+
configFile,
|
|
404
|
+
getDefaultCodingAgent,
|
|
405
|
+
getDefaultEditor,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
390
408
|
for (const [key, value] of Object.entries(api_routes_1.allApiRoutes)) {
|
|
391
409
|
if (url.pathname === key) {
|
|
392
410
|
return (0, handler_1.handleRequest)({
|
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.524",
|
|
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.524",
|
|
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.5.4",
|
|
34
34
|
"prettier": "3.8.1",
|
|
35
|
-
"remotion": "4.0.
|
|
35
|
+
"remotion": "4.0.524",
|
|
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.524",
|
|
38
|
+
"@remotion/renderer": "4.0.524",
|
|
39
|
+
"@remotion/studio-codemods": "4.0.524",
|
|
40
|
+
"@remotion/studio-shared": "4.0.524",
|
|
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.524",
|
|
49
49
|
"eslint": "9.19.0",
|
|
50
50
|
"@types/node": "20.12.14",
|
|
51
51
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|