@remotion/studio-server 4.0.519 → 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.
- package/dist/codemods/split-jsx-sequence.d.ts +0 -1
- package/dist/codemods/split-jsx-sequence.js +0 -5
- package/dist/helpers/install-command.js +1 -0
- package/dist/helpers/resolve-composition-component.d.ts +0 -1
- package/dist/helpers/resolve-composition-component.js +0 -2
- package/dist/preview-server/api-routes.js +4 -0
- package/dist/preview-server/close-and-restart.d.ts +4 -1
- package/dist/preview-server/close-and-restart.js +6 -5
- package/dist/preview-server/get-package-manager.js +6 -0
- package/dist/preview-server/routes/apply-codemod.js +16 -0
- package/dist/preview-server/routes/element-install-plan.d.ts +1 -9
- package/dist/preview-server/routes/insert-element.js +5 -8
- package/dist/preview-server/routes/insert-jsx-element.js +2 -6
- package/dist/preview-server/routes/restart-studio.js +2 -2
- package/dist/preview-server/routes/shutdown-studio.d.ts +2 -0
- package/dist/preview-server/routes/shutdown-studio.js +10 -0
- package/dist/preview-server/routes/split-jsx-sequence.js +2 -6
- package/dist/preview-server/routes/upgrade-remotion.d.ts +3 -0
- package/dist/preview-server/routes/upgrade-remotion.js +54 -0
- 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.d.ts +1 -1
- package/dist/start-studio.d.ts +2 -0
- package/dist/start-studio.js +8 -2
- package/package.json +9 -9
|
@@ -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
|
-
|
|
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((
|
|
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}"`,
|
|
@@ -2,15 +2,7 @@ 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;
|
|
@@ -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) {
|
|
@@ -23,14 +22,15 @@ const hasExpectedFileState = ({ expected, actual, }) => {
|
|
|
23
22
|
return actual.sourceHash === expected.sourceHash;
|
|
24
23
|
};
|
|
25
24
|
const insertElementHandler = ({ input: { compositionFile, compositionId, element, expectedFileState, from, position, overwriteExisting, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
|
|
26
|
-
var _a, _b;
|
|
27
25
|
try {
|
|
28
26
|
(0, element_install_plan_1.validateElementInstallPosition)(position);
|
|
29
27
|
if (from !== null &&
|
|
30
28
|
(!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
|
|
31
29
|
throw new Error('from must be a non-negative integer');
|
|
32
30
|
}
|
|
33
|
-
const installationMode =
|
|
31
|
+
const installationMode = element.installationMode === null
|
|
32
|
+
? 'wrapped'
|
|
33
|
+
: element.installationMode;
|
|
34
34
|
const componentOwnsSequence = installationMode === 'component-owned-sequence';
|
|
35
35
|
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
|
|
36
36
|
const plan = await (0, element_install_plan_1.getElementInstallPlan)({
|
|
@@ -90,7 +90,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
90
90
|
importPath: plan.importPath,
|
|
91
91
|
props: componentOwnsSequence
|
|
92
92
|
? [
|
|
93
|
-
...(element.durationInFrames ===
|
|
93
|
+
...(element.durationInFrames === null
|
|
94
94
|
? []
|
|
95
95
|
: [
|
|
96
96
|
{
|
|
@@ -109,7 +109,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
109
109
|
? null
|
|
110
110
|
: {
|
|
111
111
|
dimensions: element.dimensions,
|
|
112
|
-
durationInFrames:
|
|
112
|
+
durationInFrames: element.durationInFrames,
|
|
113
113
|
from,
|
|
114
114
|
name: element.displayName,
|
|
115
115
|
position,
|
|
@@ -206,9 +206,6 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
206
206
|
: 'Created Element source';
|
|
207
207
|
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(elementLocationLabel)} ${elementFileAction}`);
|
|
208
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}>`);
|
|
209
|
-
if (!inserted.formatted) {
|
|
210
|
-
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
211
|
-
}
|
|
212
209
|
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
213
210
|
return { success: true, nodePathMutation };
|
|
214
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,
|
|
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
|
-
|
|
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
|
-
(
|
|
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,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,
|
|
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
|
-
|
|
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,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;
|
|
@@ -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)({
|
|
@@ -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;
|
package/dist/start-studio.d.ts
CHANGED
|
@@ -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;
|
package/dist/start-studio.js
CHANGED
|
@@ -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 },
|
|
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.
|
|
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.
|
|
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
|
|
33
|
+
"zod": "4.5.4",
|
|
34
34
|
"prettier": "3.8.1",
|
|
35
|
-
"remotion": "4.0.
|
|
35
|
+
"remotion": "4.0.521",
|
|
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.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.
|
|
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"
|