init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,3 @@
import type { AddRenderRequest } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleAddRender: ApiHandler<AddRenderRequest, undefined>;

View File

@@ -0,0 +1,140 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleAddRender = void 0;
const renderer_1 = require("@remotion/renderer");
const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDirectory, methods: { addJob }, }) => {
const id = String(Math.random()).replace('0.', '');
if (input.type === 'video') {
addJob({
entryPoint,
remotionRoot,
job: {
cleanup: [],
codec: input.codec,
audioCodec: input.audioCodec,
compositionId: input.compositionId,
deletedOutputLocation: false,
type: 'video',
status: 'idle',
id,
imageFormat: input.imageFormat,
outName: input.outName,
jpegQuality: input.jpegQuality,
scale: input.scale,
startedAt: Date.now(),
logLevel: input.logLevel,
cancelToken: (0, renderer_1.makeCancelSignal)(),
concurrency: input.concurrency,
crf: input.crf,
endFrame: input.endFrame,
startFrame: input.startFrame,
muted: input.muted,
enforceAudioTrack: input.enforceAudioTrack,
proResProfile: input.proResProfile,
x264Preset: input.x264Preset,
pixelFormat: input.pixelFormat,
audioBitrate: input.audioBitrate,
videoBitrate: input.videoBitrate,
encodingMaxRate: input.encodingMaxRate,
encodingBufferSize: input.encodingBufferSize,
everyNthFrame: input.everyNthFrame,
numberOfGifLoops: input.numberOfGifLoops,
delayRenderTimeout: input.delayRenderTimeout,
disallowParallelEncoding: input.disallowParallelEncoding,
chromiumOptions: input.chromiumOptions,
envVariables: input.envVariables,
serializedInputPropsWithCustomSchema: input.serializedInputPropsWithCustomSchema,
offthreadVideoCacheSizeInBytes: input.offthreadVideoCacheSizeInBytes,
colorSpace: input.colorSpace,
multiProcessOnLinux: input.multiProcessOnLinux,
beepOnFinish: input.beepOnFinish,
repro: input.repro,
binariesDirectory,
forSeamlessAacConcatenation: input.forSeamlessAacConcatenation,
separateAudioTo: input.separateAudioTo,
metadata: input.metadata,
hardwareAcceleration: input.hardwareAcceleration,
chromeMode: input.chromeMode,
offthreadVideoThreads: input.offthreadVideoThreads,
mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
},
logLevel,
});
}
if (input.type === 'sequence') {
addJob({
entryPoint,
remotionRoot,
job: {
cleanup: [],
compositionId: input.compositionId,
deletedOutputLocation: false,
type: 'sequence',
status: 'idle',
id,
imageFormat: input.imageFormat,
outName: input.outName,
jpegQuality: input.jpegQuality,
scale: input.scale,
startedAt: Date.now(),
logLevel: input.logLevel,
cancelToken: (0, renderer_1.makeCancelSignal)(),
concurrency: input.concurrency,
endFrame: input.endFrame,
startFrame: input.startFrame,
delayRenderTimeout: input.delayRenderTimeout,
chromiumOptions: input.chromiumOptions,
envVariables: input.envVariables,
serializedInputPropsWithCustomSchema: input.serializedInputPropsWithCustomSchema,
offthreadVideoCacheSizeInBytes: input.offthreadVideoCacheSizeInBytes,
multiProcessOnLinux: input.multiProcessOnLinux,
beepOnFinish: input.beepOnFinish,
repro: input.repro,
binariesDirectory,
metadata: input.metadata,
chromeMode: input.chromeMode,
offthreadVideoThreads: input.offthreadVideoThreads,
mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
},
logLevel,
});
}
if (input.type === 'still') {
addJob({
job: {
compositionId: input.compositionId,
id: String(Math.random()).replace('0.', ''),
startedAt: Date.now(),
type: 'still',
outName: input.outName,
status: 'idle',
imageFormat: input.imageFormat,
jpegQuality: input.jpegQuality,
frame: input.frame,
scale: input.scale,
cleanup: [],
deletedOutputLocation: false,
logLevel: input.logLevel,
cancelToken: (0, renderer_1.makeCancelSignal)(),
chromiumOptions: input.chromiumOptions,
delayRenderTimeout: input.delayRenderTimeout,
envVariables: input.envVariables,
serializedInputPropsWithCustomSchema: input.serializedInputPropsWithCustomSchema,
offthreadVideoCacheSizeInBytes: input.offthreadVideoCacheSizeInBytes,
multiProcessOnLinux: input.multiProcessOnLinux,
beepOnFinish: input.beepOnFinish,
repro: false,
binariesDirectory,
metadata: input.metadata,
chromeMode: input.chromeMode,
offthreadVideoThreads: input.offthreadVideoThreads,
mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
},
entryPoint,
remotionRoot,
logLevel,
});
}
return Promise.resolve(undefined);
};
exports.handleAddRender = handleAddRender;

View File

@@ -0,0 +1,3 @@
import type { ApplyCodemodRequest, ApplyCodemodResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const applyCodemodHandler: ApiHandler<ApplyCodemodRequest, ApplyCodemodResponse>;

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyCodemodHandler = void 0;
const renderer_1 = require("@remotion/renderer");
const node_fs_1 = require("node:fs");
const duplicate_composition_1 = require("../../codemods/duplicate-composition");
const simple_diff_1 = require("../../codemods/simple-diff");
const project_info_1 = require("../project-info");
const can_update_default_props_1 = require("./can-update-default-props");
const applyCodemodHandler = async ({ input: { codemod, dryRun }, logLevel, remotionRoot, entryPoint }) => {
try {
const time = Date.now();
const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
if (!projectInfo.rootFile) {
throw new Error('Cannot find root file in project');
}
(0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
const input = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
const { newContents } = (0, duplicate_composition_1.parseAndApplyCodemod)({
codeMod: codemod,
input,
});
const formatted = await (0, duplicate_composition_1.formatOutput)(newContents);
const diff = (0, simple_diff_1.simpleDiff)({
oldLines: input.split('\n'),
newLines: formatted.split('\n'),
});
if (!dryRun) {
(0, node_fs_1.writeFileSync)(projectInfo.rootFile, formatted);
const end = Date.now() - time;
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Edited root file in ${end}ms`));
}
return {
success: true,
diff,
};
}
catch (err) {
return {
success: false,
reason: err.message,
stack: err.stack,
};
}
};
exports.applyCodemodHandler = applyCodemodHandler;

View File

@@ -0,0 +1,3 @@
import type { ApplyVisualControlRequest, ApplyVisualControlResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const applyVisualControlHandler: ApiHandler<ApplyVisualControlRequest, ApplyVisualControlResponse>;

View File

@@ -0,0 +1,35 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyVisualControlHandler = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
const parse_ast_1 = require("../../codemods/parse-ast");
const recast_mods_1 = require("../../codemods/recast-mods");
const applyVisualControlHandler = ({ input: { fileName, changes }, remotionRoot }) => {
const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
if (fileRelativeToRoot.startsWith('..')) {
throw new Error('Cannot apply visual control change to a file outside the project');
}
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
const ast = (0, parse_ast_1.parseAst)(fileContents);
const { newAst, changesMade } = (0, recast_mods_1.applyCodemod)({
file: ast,
codeMod: {
type: 'apply-visual-control',
changes,
},
});
if (changesMade.length === 0) {
throw new Error('No changes were made to the file');
}
const output = (0, parse_ast_1.serializeAst)(newAst);
(0, node_fs_1.writeFileSync)(absolutePath, output);
return Promise.resolve({
success: true,
});
};
exports.applyVisualControlHandler = applyVisualControlHandler;

View File

@@ -0,0 +1,4 @@
import type { CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const checkIfTypeScriptFile: (file: string) => void;
export declare const canUpdateDefaultPropsHandler: ApiHandler<CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse>;

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.canUpdateDefaultPropsHandler = exports.checkIfTypeScriptFile = void 0;
const node_fs_1 = require("node:fs");
const update_default_props_1 = require("../../codemods/update-default-props");
const project_info_1 = require("../project-info");
const checkIfTypeScriptFile = (file) => {
if (!file.endsWith('.tsx') &&
!file.endsWith('.ts') &&
!file.endsWith('.mtsx') &&
!file.endsWith('.mts')) {
throw new Error('Cannot update Root file if not using TypeScript');
}
};
exports.checkIfTypeScriptFile = checkIfTypeScriptFile;
const canUpdateDefaultPropsHandler = async ({ input: { compositionId }, remotionRoot, entryPoint }) => {
try {
const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
if (!projectInfo.rootFile) {
throw new Error('Cannot find root file in project');
}
(0, exports.checkIfTypeScriptFile)(projectInfo.rootFile);
await (0, update_default_props_1.updateDefaultProps)({
compositionId,
input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
newDefaultProps: {},
enumPaths: [],
});
return {
canUpdate: true,
};
}
catch (err) {
return {
canUpdate: false,
reason: err.message,
};
}
};
exports.canUpdateDefaultPropsHandler = canUpdateDefaultPropsHandler;

View File

@@ -0,0 +1,3 @@
import type { CancelRenderRequest, CancelRenderResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleCancelRender: ApiHandler<CancelRenderRequest, CancelRenderResponse>;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleCancelRender = void 0;
const handleCancelRender = ({ input: { jobId }, methods: { cancelJob } }) => {
cancelJob(jobId);
return Promise.resolve({});
};
exports.handleCancelRender = handleCancelRender;

View File

@@ -0,0 +1,3 @@
import type { DeleteStaticFileRequest, DeleteStaticFileResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const deleteStaticFileHandler: ApiHandler<DeleteStaticFileRequest, DeleteStaticFileResponse>;

View File

@@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteStaticFileHandler = void 0;
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const deleteStaticFileHandler = ({ input: { relativePath }, publicDir }) => {
const resolved = path_1.default.join(publicDir, relativePath);
const relativeToPublicDir = path_1.default.relative(publicDir, resolved);
if (relativeToPublicDir.startsWith('..')) {
throw new Error(`Not allowed to write to ${relativeToPublicDir}`);
}
const exists = (0, fs_1.existsSync)(resolved);
if (exists) {
(0, fs_1.unlinkSync)(resolved);
}
return Promise.resolve({
success: true,
existed: exists,
});
};
exports.deleteStaticFileHandler = deleteStaticFileHandler;

View File

@@ -0,0 +1,3 @@
import { type InstallPackageRequest, type InstallPackageResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleInstallPackage: ApiHandler<InstallPackageRequest, InstallPackageResponse>;

View File

@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleInstallPackage = void 0;
const renderer_1 = require("@remotion/renderer");
const studio_shared_1 = require("@remotion/studio-shared");
const node_child_process_1 = require("node:child_process");
const version_1 = require("remotion/version");
const install_command_1 = require("../../helpers/install-command");
const get_package_manager_1 = require("../get-package-manager");
const extraPackageNames = studio_shared_1.extraPackages.map((pkg) => pkg.name);
const isExtraPackage = (packageName) => {
return extraPackageNames.includes(packageName);
};
const getExtraPackageVersion = (packageName) => {
const pkg = studio_shared_1.extraPackages.find((p) => p.name === packageName);
return pkg ? pkg.version : null;
};
const handleInstallPackage = async ({ logLevel, remotionRoot, input: { packageNames } }) => {
for (const packageName of packageNames) {
if (!packageName.startsWith('@remotion/') && !isExtraPackage(packageName)) {
return Promise.reject(new Error(`Package ${packageName} is not allowed to be installed.`));
}
}
const manager = (0, get_package_manager_1.getPackageManager)(remotionRoot, undefined, 0);
if (manager === 'unknown') {
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!`);
}
// Build packages with appropriate versions
const packagesWithVersions = packageNames.map((pkg) => {
const extraVersion = getExtraPackageVersion(pkg);
if (extraVersion) {
return `${pkg}@${extraVersion}`;
}
return `${pkg}@${version_1.VERSION}`;
});
const command = (0, install_command_1.getInstallCommand)({
manager: manager.manager,
packages: packagesWithVersions,
version: '',
additionalArgs: [],
});
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray(`╭─ ${manager.manager} ${command.join(' ')}`));
const time = Date.now();
try {
await new Promise((resolve, reject) => {
const cmd = (0, node_child_process_1.spawn)(manager.manager, command, {});
cmd.stdout.on('data', (d) => {
const splitted = d.toString().trim().split('\n');
splitted.forEach((line) => {
renderer_1.RenderInternals.Log.info({ indent: true, logLevel }, line);
});
});
cmd.stdout.on('end', () => {
resolve();
});
cmd.on('close', (code, signal) => {
if (code === 0) {
resolve();
}
else {
reject(new Error(`Command exited with code ${code} and signal ${signal}`));
}
});
});
const timeEnd = Date.now();
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray('╰─ '), `Done in ${timeEnd - time}ms`);
return Promise.resolve({});
}
catch (err) {
const timeEnd = Date.now();
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray('╰─ '), renderer_1.RenderInternals.chalk.red(`Errored in ${timeEnd - time}ms`));
return Promise.reject(err);
}
};
exports.handleInstallPackage = handleInstallPackage;

View File

@@ -0,0 +1,3 @@
import type { OpenInFileExplorerRequest } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleOpenInFileExplorer: ApiHandler<OpenInFileExplorerRequest, void>;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleOpenInFileExplorer = void 0;
const open_directory_in_finder_1 = require("../../open-directory-in-finder");
const handleOpenInFileExplorer = ({ input: { directory }, remotionRoot }) => {
return (0, open_directory_in_finder_1.openDirectoryInFinder)(directory, remotionRoot);
};
exports.handleOpenInFileExplorer = handleOpenInFileExplorer;

View File

@@ -0,0 +1,3 @@
import type { ProjectInfoRequest, ProjectInfoResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const projectInfoHandler: ApiHandler<ProjectInfoRequest, ProjectInfoResponse>;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.projectInfoHandler = void 0;
const project_info_1 = require("../project-info");
const projectInfoHandler = async ({ remotionRoot, entryPoint }) => {
const info = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
return { projectInfo: info };
};
exports.projectInfoHandler = projectInfoHandler;

View File

@@ -0,0 +1,3 @@
import type { RemoveRenderRequest } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleRemoveRender: ApiHandler<RemoveRenderRequest, undefined>;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleRemoveRender = void 0;
const handleRemoveRender = ({ input: { jobId }, methods: { removeJob }, }) => {
removeJob(jobId);
return Promise.resolve(undefined);
};
exports.handleRemoveRender = handleRemoveRender;

View File

@@ -0,0 +1,3 @@
import type { RestartStudioRequest, RestartStudioResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleRestartStudio: ApiHandler<RestartStudioRequest, RestartStudioResponse>;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleRestartStudio = void 0;
const close_and_restart_1 = require("../close-and-restart");
const handleRestartStudio = () => {
(0, close_and_restart_1.signalRestart)();
return Promise.resolve({});
};
exports.handleRestartStudio = handleRestartStudio;

View File

@@ -0,0 +1,3 @@
import type { SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const subscribeToFileExistence: ApiHandler<SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse>;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.subscribeToFileExistence = void 0;
const file_existence_watchers_1 = require("../file-existence-watchers");
const subscribeToFileExistence = ({ input: { file, clientId }, remotionRoot }) => {
const { exists } = (0, file_existence_watchers_1.subscribeToFileExistenceWatchers)({
file,
remotionRoot,
clientId,
});
return Promise.resolve({ exists });
};
exports.subscribeToFileExistence = subscribeToFileExistence;

View File

@@ -0,0 +1,3 @@
import type { UnsubscribeFromFileExistenceRequest } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const unsubscribeFromFileExistence: ApiHandler<UnsubscribeFromFileExistenceRequest, undefined>;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unsubscribeFromFileExistence = void 0;
const file_existence_watchers_1 = require("../file-existence-watchers");
const unsubscribeFromFileExistence = ({ input, remotionRoot }) => {
(0, file_existence_watchers_1.unsubscribeFromFileExistenceWatchers)({
file: input.file,
clientId: input.clientId,
remotionRoot,
});
return Promise.resolve(undefined);
};
exports.unsubscribeFromFileExistence = unsubscribeFromFileExistence;

View File

@@ -0,0 +1,3 @@
import type { UpdateAvailableRequest, UpdateAvailableResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const handleUpdate: ApiHandler<UpdateAvailableRequest, UpdateAvailableResponse>;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleUpdate = void 0;
const update_available_1 = require("../update-available");
const handleUpdate = async ({ remotionRoot }) => {
const data = await (0, update_available_1.isUpdateAvailableWithTimeout)(remotionRoot);
return data;
};
exports.handleUpdate = handleUpdate;

View File

@@ -0,0 +1,3 @@
import type { UpdateDefaultPropsRequest, UpdateDefaultPropsResponse } from '@remotion/studio-shared';
import type { ApiHandler } from '../api-types';
export declare const updateDefaultPropsHandler: ApiHandler<UpdateDefaultPropsRequest, UpdateDefaultPropsResponse>;

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDefaultPropsHandler = void 0;
const node_fs_1 = require("node:fs");
const update_default_props_1 = require("../../codemods/update-default-props");
const project_info_1 = require("../project-info");
const can_update_default_props_1 = require("./can-update-default-props");
const updateDefaultPropsHandler = async ({ input: { compositionId, defaultProps, enumPaths }, remotionRoot, entryPoint, }) => {
try {
const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
if (!projectInfo.rootFile) {
throw new Error('Cannot find root file in project');
}
(0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
const updated = await (0, update_default_props_1.updateDefaultProps)({
compositionId,
input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
newDefaultProps: JSON.parse(defaultProps),
enumPaths,
});
(0, node_fs_1.writeFileSync)(projectInfo.rootFile, updated);
return {
success: true,
};
}
catch (err) {
return {
success: false,
reason: err.message,
stack: err.stack,
};
}
};
exports.updateDefaultPropsHandler = updateDefaultPropsHandler;