@remotion/studio-server 4.0.520 → 4.0.521

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.
@@ -7,7 +7,6 @@ export declare const splitJsxSequence: ({ input, nodePath, sequenceKeys, splitFr
7
7
  prettierConfigOverride?: Record<string, unknown> | null | undefined;
8
8
  }) => Promise<{
9
9
  output: string;
10
- formatted: boolean;
11
10
  nodeLabel: string;
12
11
  logLine: number;
13
12
  nodePathRemappings: import("@remotion/studio-shared").SequenceNodePathRemapping[];
@@ -2,16 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.splitJsxSequence = void 0;
4
4
  const studio_codemods_1 = require("@remotion/studio-codemods");
5
- const format_file_content_1 = require("./format-file-content");
6
5
  const splitJsxSequence = ({ input, nodePath, sequenceKeys, splitFrame, prettierConfigOverride, }) => (0, studio_codemods_1.splitJsxSequence)({
7
6
  input,
8
7
  nodePath,
9
8
  sequenceKeys,
10
9
  splitFrame,
11
- formatFile: ({ contents, prettierConfigOverride: override }) => (0, format_file_content_1.formatFileContent)({
12
- input: contents,
13
- prettierConfigOverride: override,
14
- }),
15
10
  prettierConfigOverride,
16
11
  });
17
12
  exports.splitJsxSequence = splitJsxSequence;
@@ -15,6 +15,7 @@ const getInstallCommand = ({ manager, packages, version, additionalArgs, }) => {
15
15
  pnpm: ['i', ...additionalArgs, ...pkgList],
16
16
  yarn: ['add', '--exact', ...additionalArgs, ...pkgList],
17
17
  bun: ['i', ...additionalArgs, ...pkgList],
18
+ nub: ['add', ...additionalArgs, ...pkgList],
18
19
  };
19
20
  return commands[manager];
20
21
  };
@@ -34,7 +34,6 @@ export declare const insertJsxElementIntoComposition: ({ remotionRoot, compositi
34
34
  source: string;
35
35
  oldContents: string;
36
36
  output: string;
37
- formatted: boolean;
38
37
  logLine: number;
39
38
  nodePathRemappings: SequenceNodePathRemapping[];
40
39
  insertedNodePath: SequenceNodePath | null;
@@ -7,13 +7,11 @@ exports.insertJsxElementIntoComposition = exports.resolveCompositionComponent =
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const studio_codemods_1 = require("@remotion/studio-codemods");
10
- const format_file_content_1 = require("../codemods/format-file-content");
11
10
  const svg_to_jsx_1 = require("./svg-to-jsx");
12
11
  const makeCodemodEnvironment = (remotionRoot) => ({
13
12
  dirname: node_path_1.default.dirname,
14
13
  extname: node_path_1.default.extname,
15
14
  fileExists: (fileName) => node_fs_1.default.existsSync(fileName) && node_fs_1.default.statSync(fileName).isFile(),
16
- formatFile: ({ contents, prettierConfigOverride }) => (0, format_file_content_1.formatFileContent)({ input: contents, prettierConfigOverride }),
17
15
  isAbsolute: node_path_1.default.isAbsolute,
18
16
  join: node_path_1.default.join,
19
17
  pathSeparator: node_path_1.default.sep,
@@ -47,6 +47,7 @@ const restart_studio_1 = require("./routes/restart-studio");
47
47
  const save_effect_props_1 = require("./routes/save-effect-props");
48
48
  const save_multiple_effect_props_1 = require("./routes/save-multiple-effect-props");
49
49
  const save_sequence_props_1 = require("./routes/save-sequence-props");
50
+ const shutdown_studio_1 = require("./routes/shutdown-studio");
50
51
  const split_jsx_sequence_1 = require("./routes/split-jsx-sequence");
51
52
  const split_video_from_audio_1 = require("./routes/split-video-from-audio");
52
53
  const subscribe_to_default_props_1 = require("./routes/subscribe-to-default-props");
@@ -62,6 +63,7 @@ const update_default_props_1 = require("./routes/update-default-props");
62
63
  const update_effect_keyframe_settings_1 = require("./routes/update-effect-keyframe-settings");
63
64
  const update_element_install_target_1 = require("./routes/update-element-install-target");
64
65
  const update_sequence_keyframe_settings_1 = require("./routes/update-sequence-keyframe-settings");
66
+ const upgrade_remotion_1 = require("./routes/upgrade-remotion");
65
67
  exports.allApiRoutes = {
66
68
  '/api/composition-component-info': composition_component_info_1.compositionComponentInfoHandler,
67
69
  '/api/copy-render-output-to-asset': copy_render_output_to_asset_1.copyRenderOutputToAssetHandler,
@@ -113,6 +115,8 @@ exports.allApiRoutes = {
113
115
  '/api/project-info': project_info_1.projectInfoHandler,
114
116
  '/api/delete-static-file': delete_static_file_1.deleteStaticFileHandler,
115
117
  '/api/rename-static-file': rename_static_file_1.renameStaticFileHandler,
118
+ '/api/upgrade-remotion': upgrade_remotion_1.handleUpgradeRemotion,
119
+ '/api/shutdown-studio': shutdown_studio_1.handleShutdownStudio,
116
120
  '/api/restart-studio': restart_studio_1.handleRestartStudio,
117
121
  '/api/default-coding-agent-info': default_coding_agent_1.getDefaultCodingAgentInfoHandler,
118
122
  '/api/default-editor-info': default_editor_1.getDefaultEditorInfoHandler,
@@ -1,2 +1,5 @@
1
- export declare const noOpUntilRestart: () => Promise<void>;
1
+ type StudioAction = 'restart' | 'shutdown';
2
+ export declare const noOpUntilRestart: () => Promise<StudioAction>;
2
3
  export declare const signalRestart: () => void;
4
+ export declare const signalShutdown: () => void;
5
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.signalRestart = exports.noOpUntilRestart = void 0;
3
+ exports.signalShutdown = exports.signalRestart = exports.noOpUntilRestart = void 0;
4
4
  const resolveFunctions = [];
5
5
  const noOpUntilRestart = () => {
6
6
  return new Promise((resolve) => {
@@ -9,9 +9,10 @@ const noOpUntilRestart = () => {
9
9
  };
10
10
  exports.noOpUntilRestart = noOpUntilRestart;
11
11
  const signalRestart = () => {
12
- resolveFunctions.forEach((f) => {
13
- f();
14
- });
15
- resolveFunctions.length = 0;
12
+ resolveFunctions.splice(0).forEach((resolve) => resolve('restart'));
16
13
  };
17
14
  exports.signalRestart = signalRestart;
15
+ const signalShutdown = () => {
16
+ resolveFunctions.splice(0).forEach((resolve) => resolve('shutdown'));
17
+ };
18
+ exports.signalShutdown = signalShutdown;
@@ -26,6 +26,12 @@ exports.lockFilePaths = [
26
26
  installCommand: 'pnpm i',
27
27
  startCommand: 'pnpm exec remotion studio',
28
28
  },
29
+ {
30
+ path: 'nub.lock',
31
+ manager: 'nub',
32
+ installCommand: 'nub add',
33
+ startCommand: 'nubx remotion studio',
34
+ },
29
35
  {
30
36
  path: 'bun.lock',
31
37
  manager: 'bun',
@@ -68,6 +68,12 @@ const getCodemodLogMessage = (codemod) => {
68
68
  : 'to root';
69
69
  return `Moved composition "${codemod.idToMove}" ${destination}`;
70
70
  }
71
+ if (codemod.type === 'move-composition-or-folder') {
72
+ const source = codemod.source.type === 'composition'
73
+ ? `composition "${codemod.source.compositionId}"`
74
+ : `folder "${getFolderPath(codemod.source.parentName, codemod.source.folderName)}"`;
75
+ return `Moved ${source}`;
76
+ }
71
77
  if (codemod.type === 'rename-folder') {
72
78
  const oldName = getFolderPath(codemod.parentName, codemod.folderName);
73
79
  const newName = getFolderPath(codemod.parentName, codemod.newName);
@@ -130,6 +136,16 @@ const getCodemodUndoDescription = (codemod) => {
130
136
  entryType: codemod.type,
131
137
  };
132
138
  }
139
+ if (codemod.type === 'move-composition-or-folder') {
140
+ const label = codemod.source.type === 'composition'
141
+ ? `composition "${codemod.source.compositionId}"`
142
+ : `folder "${getFolderPath(codemod.source.parentName, codemod.source.folderName)}"`;
143
+ return {
144
+ undoMessage: `↩️ Move of ${label}`,
145
+ redoMessage: `↪️ Move of ${label}`,
146
+ entryType: codemod.type,
147
+ };
148
+ }
133
149
  if (codemod.type === 'new-composition') {
134
150
  return {
135
151
  undoMessage: `↩️ Creation of composition "${codemod.newId}"`,
@@ -8,7 +8,6 @@ const format_log_file_location_1 = require("../format-log-file-location");
8
8
  const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
9
9
  const undo_stack_1 = require("../undo-stack");
10
10
  const element_install_plan_1 = require("./element-install-plan");
11
- const log_update_1 = require("./log-updates/log-update");
12
11
  const source_file_write_queue_1 = require("./source-file-write-queue");
13
12
  const hasExpectedFileState = ({ expected, actual, }) => {
14
13
  if (expected.exists !== actual.exists) {
@@ -207,9 +206,6 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
207
206
  : 'Created Element source';
208
207
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(elementLocationLabel)} ${elementFileAction}`);
209
208
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(compositionLocationLabel)} Added <${plan.componentName}>`);
210
- if (!inserted.formatted) {
211
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
212
- }
213
209
  (0, undo_stack_1.printUndoHint)(logLevel);
214
210
  return { success: true, nodePathMutation };
215
211
  }
@@ -13,7 +13,6 @@ const resolve_composition_component_1 = require("../../helpers/resolve-compositi
13
13
  const format_log_file_location_1 = require("../format-log-file-location");
14
14
  const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
15
15
  const undo_stack_1 = require("../undo-stack");
16
- const log_update_1 = require("./log-updates/log-update");
17
16
  const source_file_write_queue_1 = require("./source-file-write-queue");
18
17
  const validateDimension = (name, value) => {
19
18
  if (!Number.isFinite(value) || value < 1) {
@@ -159,7 +158,7 @@ const insertJsxElementHandler = ({ input: { compositionFile, compositionId, elem
159
158
  }
160
159
  const elementLabel = getElementLabel(element);
161
160
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-jsx-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.type}"`);
162
- const { fileName, source, oldContents, output, formatted, insertedNodePath, logLine, nodePathRemappings, } = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
161
+ const { fileName, source, oldContents, output, insertedNodePath, logLine, nodePathRemappings, } = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
163
162
  remotionRoot,
164
163
  compositionFile,
165
164
  compositionId,
@@ -204,10 +203,7 @@ const insertJsxElementHandler = ({ input: { compositionFile, compositionId, elem
204
203
  line: logLine,
205
204
  });
206
205
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Added ${elementLabel}`);
207
- if (!formatted) {
208
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
209
- }
210
- renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[insert-jsx-element] Wrote ${source}${formatted ? ' (formatted)' : ''}`);
206
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[insert-jsx-element] Wrote ${source}`);
211
207
  (0, undo_stack_1.printUndoHint)(logLevel);
212
208
  return {
213
209
  success: true,
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleRestartStudio = void 0;
4
4
  const close_and_restart_1 = require("../close-and-restart");
5
- const handleRestartStudio = () => {
6
- (0, close_and_restart_1.signalRestart)();
5
+ const handleRestartStudio = ({ response }) => {
6
+ response.once('finish', close_and_restart_1.signalRestart);
7
7
  return Promise.resolve({});
8
8
  };
9
9
  exports.handleRestartStudio = handleRestartStudio;
@@ -0,0 +1,2 @@
1
+ import type { ApiHandler } from '../api-types';
2
+ export declare const handleShutdownStudio: ApiHandler<{}, {}>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleShutdownStudio = void 0;
4
+ const close_and_restart_1 = require("../close-and-restart");
5
+ const handleShutdownStudio = ({ response }) => {
6
+ // Flush the acknowledgement before closing the HTTP and live-event connections.
7
+ response.once('finish', close_and_restart_1.signalShutdown);
8
+ return Promise.resolve({});
9
+ };
10
+ exports.handleShutdownStudio = handleShutdownStudio;
@@ -9,7 +9,6 @@ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside
9
9
  const format_log_file_location_1 = require("../format-log-file-location");
10
10
  const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
11
11
  const undo_stack_1 = require("../undo-stack");
12
- const log_update_1 = require("./log-updates/log-update");
13
12
  const source_file_write_queue_1 = require("./source-file-write-queue");
14
13
  const splitJsxSequenceHandler = ({ input: { fileName, nodePath, sequenceKeys, splitFrame }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
15
14
  try {
@@ -20,7 +19,7 @@ const splitJsxSequenceHandler = ({ input: { fileName, nodePath, sequenceKeys, sp
20
19
  action: 'modify',
21
20
  });
22
21
  const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
23
- const { output, formatted, nodeLabel, logLine, nodePathRemappings } = await (0, split_jsx_sequence_1.splitJsxSequence)({
22
+ const { output, nodeLabel, logLine, nodePathRemappings } = await (0, split_jsx_sequence_1.splitJsxSequence)({
24
23
  input: fileContents,
25
24
  nodePath,
26
25
  sequenceKeys,
@@ -60,10 +59,7 @@ const splitJsxSequenceHandler = ({ input: { fileName, nodePath, sequenceKeys, sp
60
59
  line: logLine,
61
60
  });
62
61
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Split ${nodeLabel}`);
63
- if (!formatted) {
64
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
65
- }
66
- renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[split-jsx-sequence] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
62
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[split-jsx-sequence] Wrote ${fileRelativeToRoot}`);
67
63
  (0, undo_stack_1.printUndoHint)(logLevel);
68
64
  return {
69
65
  success: true,
@@ -0,0 +1,3 @@
1
+ import type { ApiRoutes } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const handleUpgradeRemotion: ApiHandler<ApiRoutes['/api/upgrade-remotion']['Request'], ApiRoutes['/api/upgrade-remotion']['Response']>;
@@ -0,0 +1,54 @@
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.handleUpgradeRemotion = void 0;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const renderer_1 = require("@remotion/renderer");
10
+ let upgrading = false;
11
+ const handleUpgradeRemotion = async ({ remotionRoot, logLevel, input: { version } }) => {
12
+ if (typeof version !== 'string' || !/^\d+\.\d+\.\d+$/.test(version)) {
13
+ throw new Error('Invalid Remotion version.');
14
+ }
15
+ if (upgrading) {
16
+ throw new Error('A Remotion upgrade is already in progress.');
17
+ }
18
+ upgrading = true;
19
+ try {
20
+ const cliPackage = require.resolve('@remotion/cli/package.json', {
21
+ paths: [remotionRoot],
22
+ });
23
+ const cli = node_path_1.default.join(node_path_1.default.dirname(cliPackage), 'remotion-cli.js');
24
+ await new Promise((resolve, reject) => {
25
+ const child = (0, node_child_process_1.spawn)(process.execPath, [cli, 'upgrade', `--version=${version}`], {
26
+ cwd: remotionRoot,
27
+ stdio: ['ignore', 'pipe', 'pipe'],
28
+ env: { ...process.env, CI: '1' },
29
+ });
30
+ let output = '';
31
+ const onOutput = (chunk) => {
32
+ const message = chunk.toString();
33
+ output = (output + message).slice(-8000);
34
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, message.trimEnd());
35
+ };
36
+ child.stdout.on('data', onOutput);
37
+ child.stderr.on('data', onOutput);
38
+ child.on('error', reject);
39
+ child.on('close', (code, signal) => {
40
+ if (code === 0) {
41
+ resolve();
42
+ }
43
+ else {
44
+ reject(new Error(`Remotion upgrade failed (exit code ${code}, signal ${signal}).\n${output}`));
45
+ }
46
+ });
47
+ });
48
+ return {};
49
+ }
50
+ finally {
51
+ upgrading = false;
52
+ }
53
+ };
54
+ exports.handleUpgradeRemotion = handleUpgradeRemotion;
@@ -4,7 +4,7 @@ export interface UndoEntryDescription {
4
4
  undoMessage: string;
5
5
  redoMessage: string;
6
6
  }
7
- type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-node' | 'duplicate-jsx-node' | 'split-jsx-sequence' | 'split-video-from-audio' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-to-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
7
+ type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-node' | 'duplicate-jsx-node' | 'split-jsx-sequence' | 'split-video-from-audio' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-to-folder' | 'move-composition-or-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
8
8
  type UndoEntrySnapshot = {
9
9
  filePath: string;
10
10
  oldContents: string | null;
@@ -6,6 +6,8 @@ export type StartStudioResult = {
6
6
  type: 'restarted';
7
7
  } | {
8
8
  type: 'already-running';
9
+ } | {
10
+ type: 'shutdown';
9
11
  };
10
12
  export declare const startStudio: ({ browserArgs, browserFlag, shouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, remotionRoot, relativePublicDir, bundlerOverride, rspackOverride, webpackOverride, poll, getRenderDefaults, getRenderQueue, getNumberOfAudioTags, queueMethods, previewEntry, gitSource, binariesDirectory, forceIPv4, getAudioLatencyHint, getExperimentalKeepAudioContextAlive, getPreviewSampleRate, enableCrossSiteIsolation, forceNew, rspack, getStudioRuntimeConfig, getDefaultCodingAgent, getDefaultEditor, configFile, }: {
11
13
  browserArgs: string;
@@ -130,6 +130,7 @@ const startStudio = async ({ browserArgs, browserFlag, shouldOpenBrowser, fullEn
130
130
  url: studioUrl,
131
131
  logLevel,
132
132
  });
133
+ let action;
133
134
  try {
134
135
  await (0, maybe_open_browser_1.maybeOpenBrowser)({
135
136
  browserArgs,
@@ -138,15 +139,20 @@ const startStudio = async ({ browserArgs, browserFlag, shouldOpenBrowser, fullEn
138
139
  url: studioUrl,
139
140
  logLevel,
140
141
  });
141
- await (0, close_and_restart_1.noOpUntilRestart)();
142
+ action = await (0, close_and_restart_1.noOpUntilRestart)();
142
143
  }
143
144
  finally {
144
145
  openBrowserShortcut.cleanup();
145
146
  }
146
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Closing server to restart...');
147
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, action === 'shutdown'
148
+ ? 'Shutting down Studio...'
149
+ : 'Closing server to restart...');
147
150
  await liveEventsServer.closeConnections();
148
151
  cleanupLiveEventsListener();
149
152
  await close();
153
+ if (action === 'shutdown') {
154
+ return { type: 'shutdown' };
155
+ }
150
156
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue('Restarting server...'));
151
157
  return { type: 'restarted' };
152
158
  };
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.520",
6
+ "version": "4.0.521",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -23,21 +23,21 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@remotion/studio-protocol": "4.0.520",
26
+ "@remotion/studio-protocol": "4.0.521",
27
27
  "@babel/types": "7.24.0",
28
28
  "@babel/parser": "7.24.1",
29
29
  "@svgr/core": "8.1.0",
30
30
  "@svgr/plugin-jsx": "8.1.0",
31
31
  "kiwi-schema": "0.5.0",
32
32
  "semver": "7.5.3",
33
- "zod": "4.4.3",
33
+ "zod": "4.5.4",
34
34
  "prettier": "3.8.1",
35
- "remotion": "4.0.520",
35
+ "remotion": "4.0.521",
36
36
  "recast": "0.23.21",
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",
37
+ "@remotion/bundler": "4.0.521",
38
+ "@remotion/renderer": "4.0.521",
39
+ "@remotion/studio-codemods": "4.0.521",
40
+ "@remotion/studio-shared": "4.0.521",
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.520",
48
+ "@remotion/eslint-config-internal": "4.0.521",
49
49
  "eslint": "9.19.0",
50
50
  "@types/node": "20.12.14",
51
51
  "@typescript/native-preview": "7.0.0-dev.20260217.1"