@remotion/studio-server 4.0.523 → 4.0.525

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.
Files changed (52) hide show
  1. package/dist/canvas-capture/generate-canvas-capture-composition.d.ts +1 -1
  2. package/dist/canvas-capture/generate-canvas-capture-composition.js +77 -12
  3. package/dist/codemods/add-effect.d.ts +1 -26
  4. package/dist/codemods/add-effect.js +6 -191
  5. package/dist/codemods/apply-codemod-to-file.js +8 -1
  6. package/dist/codemods/delete-effect.d.ts +1 -30
  7. package/dist/codemods/delete-effect.js +4 -126
  8. package/dist/codemods/duplicate-effect.d.ts +1 -26
  9. package/dist/codemods/duplicate-effect.js +4 -90
  10. package/dist/codemods/paste-effects.d.ts +9 -14
  11. package/dist/codemods/paste-effects.js +2 -170
  12. package/dist/codemods/reorder-effect.d.ts +1 -13
  13. package/dist/codemods/reorder-effect.js +2 -58
  14. package/dist/codemods/update-effect-props/update-effect-props.d.ts +2 -67
  15. package/dist/codemods/update-effect-props/update-effect-props.js +8 -312
  16. package/dist/codemods/update-keyframes/update-keyframes.js +2 -7
  17. package/dist/codemods/update-sequence-props/update-sequence-props.js +20 -58
  18. package/dist/helpers/resolve-composition-component.d.ts +2 -1
  19. package/dist/helpers/resolve-composition-component.js +13 -7
  20. package/dist/preview-server/api-routes.js +5 -0
  21. package/dist/preview-server/routes/add-keyframes.js +1 -0
  22. package/dist/preview-server/routes/apply-codemod.d.ts +19 -0
  23. package/dist/preview-server/routes/apply-codemod.js +17 -56
  24. package/dist/preview-server/routes/batch-update-keyframe-settings.js +1 -0
  25. package/dist/preview-server/routes/delete-keyframes.js +1 -0
  26. package/dist/preview-server/routes/duplicate-jsx-node.js +1 -0
  27. package/dist/preview-server/routes/insert-element.js +150 -29
  28. package/dist/preview-server/routes/insert-jsx-element.js +1 -0
  29. package/dist/preview-server/routes/install-remotion-skill.d.ts +4 -0
  30. package/dist/preview-server/routes/install-remotion-skill.js +108 -0
  31. package/dist/preview-server/routes/invalidate-bundle.d.ts +3 -0
  32. package/dist/preview-server/routes/invalidate-bundle.js +11 -0
  33. package/dist/preview-server/routes/move-keyframes.js +1 -0
  34. package/dist/preview-server/routes/save-multiple-effect-props.js +1 -0
  35. package/dist/preview-server/routes/save-sequence-props.js +1 -0
  36. package/dist/preview-server/studio-protocol/handle-discovery.js +1 -1
  37. package/dist/preview-server/studio-protocol/handle-element-library.js +1 -1
  38. package/dist/preview-server/studio-protocol/handle-install.js +4 -3
  39. package/dist/preview-server/studio-protocol/handle-license-key.js +1 -1
  40. package/dist/preview-server/studio-protocol/origin-policy.d.ts +1 -1
  41. package/dist/preview-server/studio-protocol/origin-policy.js +13 -6
  42. package/dist/preview-server/undo-stack.d.ts +4 -2
  43. package/dist/preview-server/undo-stack.js +22 -4
  44. package/dist/preview-server/watch-ignore-next-change.d.ts +1 -0
  45. package/dist/preview-server/watch-ignore-next-change.js +20 -12
  46. package/package.json +8 -8
  47. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +0 -3
  48. package/dist/preview-server/routes/delete-effect-keyframe.js +0 -89
  49. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +0 -3
  50. package/dist/preview-server/routes/delete-sequence-keyframe.js +0 -82
  51. package/dist/preview-server/routes/save-props-mutex.d.ts +0 -1
  52. package/dist/preview-server/routes/save-props-mutex.js +0 -11
@@ -3,43 +3,20 @@ 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.applyCodemodHandler = exports.getCodemodLogMessage = void 0;
6
+ exports.applyCodemodHandler = exports.getCodemodLogMessage = exports.formatNewCompositionFile = void 0;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const renderer_1 = require("@remotion/renderer");
10
10
  const studio_codemods_1 = require("@remotion/studio-codemods");
11
- const generate_canvas_capture_composition_1 = require("../../canvas-capture/generate-canvas-capture-composition");
12
11
  const apply_codemod_to_file_1 = require("../../codemods/apply-codemod-to-file");
13
- const duplicate_composition_1 = require("../../codemods/duplicate-composition");
14
12
  const file_watcher_1 = require("../../file-watcher");
15
13
  const format_log_file_location_1 = require("../format-log-file-location");
16
14
  const project_info_1 = require("../project-info");
17
15
  const undo_stack_1 = require("../undo-stack");
18
16
  const can_update_default_props_1 = require("./can-update-default-props");
19
17
  const source_file_write_queue_1 = require("./source-file-write-queue");
20
- const formatNewCompositionFile = (codemod) => {
21
- if (codemod.canvasCapture !== null) {
22
- return (0, generate_canvas_capture_composition_1.generateCanvasCaptureComposition)({
23
- componentName: codemod.componentName,
24
- compositionId: codemod.newId,
25
- data: codemod.canvasCapture.data,
26
- durationInFrames: codemod.newDurationInFrames,
27
- fps: codemod.newFps,
28
- height: codemod.newHeight,
29
- keyframeFps: codemod.canvasCapture.keyframeFps,
30
- videoFileName: codemod.canvasCapture.videoFileName,
31
- videoHeight: codemod.canvasCapture.videoHeight,
32
- videoWidth: codemod.canvasCapture.videoWidth,
33
- width: codemod.newWidth,
34
- });
35
- }
36
- return (0, duplicate_composition_1.formatOutput)(`import React from 'react';
37
-
38
- export const ${codemod.componentName}: React.FC = () => {
39
- return null;
40
- };
41
- `);
42
- };
18
+ const formatNewCompositionFile = (codemod) => (0, studio_codemods_1.makeNewCompositionComponentSource)(codemod);
19
+ exports.formatNewCompositionFile = formatNewCompositionFile;
43
20
  const getFolderPath = (parentName, folderName) => {
44
21
  return parentName ? `${parentName}/${folderName}` : folderName;
45
22
  };
@@ -185,7 +162,7 @@ const getCodemodUndoDescription = (codemod) => {
185
162
  entryType: 'visual-control',
186
163
  };
187
164
  };
188
- const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, logLevel, remotionRoot, entryPoint, }) => {
165
+ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack, undoRedoNavigation }, logLevel, remotionRoot, entryPoint, }) => {
189
166
  return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
190
167
  var _a;
191
168
  try {
@@ -232,7 +209,7 @@ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, lo
232
209
  if (componentFilePath === null) {
233
210
  throw new Error('Could not determine the new component file path');
234
211
  }
235
- componentFileContents = await formatNewCompositionFile(codemod);
212
+ componentFileContents = await (0, exports.formatNewCompositionFile)(codemod);
236
213
  snapshots.push({
237
214
  filePath: componentFilePath,
238
215
  oldContents: null,
@@ -240,35 +217,19 @@ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, lo
240
217
  logLine: 1,
241
218
  nodePathRemappings: null,
242
219
  });
243
- (0, undo_stack_1.pushTransactionToUndoStack)({
244
- snapshots,
245
- logLevel,
246
- remotionRoot,
247
- description: {
248
- undoMessage,
249
- redoMessage,
250
- },
251
- entryType,
252
- suppressHmrOnFileRestore: false,
253
- });
254
- }
255
- else {
256
- (0, undo_stack_1.pushToUndoStack)({
257
- filePath,
258
- oldContents: input,
259
- newContents: null,
260
- logLevel,
261
- remotionRoot,
262
- logLine,
263
- description: {
264
- undoMessage,
265
- redoMessage,
266
- },
267
- entryType,
268
- suppressHmrOnFileRestore: false,
269
- nodePathRemappings: null,
270
- });
271
220
  }
221
+ (0, undo_stack_1.pushTransactionToUndoStack)({
222
+ snapshots,
223
+ logLevel,
224
+ remotionRoot,
225
+ description: {
226
+ undoMessage,
227
+ redoMessage,
228
+ },
229
+ entryType,
230
+ suppressHmrOnFileRestore: false,
231
+ undoRedoNavigation,
232
+ });
272
233
  (0, undo_stack_1.suppressUndoStackInvalidation)(filePath);
273
234
  if (componentFilePath) {
274
235
  (0, undo_stack_1.suppressUndoStackInvalidation)(componentFilePath);
@@ -151,6 +151,7 @@ const batchUpdateKeyframeSettings = async ({ sequenceKeyframes, effectKeyframes,
151
151
  },
152
152
  entryType: sequenceKeyframes.length > 0 ? 'sequence-props' : 'effect-props',
153
153
  suppressHmrOnFileRestore: true,
154
+ undoRedoNavigation: null,
154
155
  });
155
156
  for (const snapshot of snapshots) {
156
157
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
@@ -186,6 +186,7 @@ const deleteKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, r
186
186
  ? 'sequence-props'
187
187
  : 'effect-props',
188
188
  suppressHmrOnFileRestore: true,
189
+ undoRedoNavigation: null,
189
190
  });
190
191
  for (const snapshot of snapshots) {
191
192
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
@@ -70,6 +70,7 @@ const duplicateJsxNodeHandler = ({ input: { nodes }, remotionRoot, logLevel }) =
70
70
  },
71
71
  entryType: 'duplicate-jsx-node',
72
72
  suppressHmrOnFileRestore: false,
73
+ undoRedoNavigation: null,
73
74
  });
74
75
  for (const update of updates) {
75
76
  (0, undo_stack_1.suppressUndoStackInvalidation)(update.absolutePath);
@@ -1,12 +1,21 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.insertElementHandler = void 0;
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = __importDefault(require("node:path"));
4
9
  const renderer_1 = require("@remotion/renderer");
10
+ const apply_codemod_to_file_1 = require("../../codemods/apply-codemod-to-file");
5
11
  const file_watcher_1 = require("../../file-watcher");
6
12
  const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
7
13
  const format_log_file_location_1 = require("../format-log-file-location");
14
+ const project_info_1 = require("../project-info");
8
15
  const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
9
16
  const undo_stack_1 = require("../undo-stack");
17
+ const apply_codemod_1 = require("./apply-codemod");
18
+ const can_update_default_props_1 = require("./can-update-default-props");
10
19
  const element_install_plan_1 = require("./element-install-plan");
11
20
  const source_file_write_queue_1 = require("./source-file-write-queue");
12
21
  const hasExpectedFileState = ({ expected, actual, }) => {
@@ -21,7 +30,9 @@ const hasExpectedFileState = ({ expected, actual, }) => {
21
30
  }
22
31
  return actual.sourceHash === expected.sourceHash;
23
32
  };
24
- const insertElementHandler = ({ input: { compositionFile, compositionId, element, installationName, expectedFileState, from, position, overwriteExisting, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
33
+ const insertElementHandler = ({ input: { compositionFile, compositionId, element, installationName, expectedFileState, from, position, overwriteExisting, undoRedoNavigation, newComposition, }, entryPoint, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
34
+ var _a, _b, _c;
35
+ var _d, _e, _f;
25
36
  try {
26
37
  (0, element_install_plan_1.validateElementInstallPosition)(position);
27
38
  if (from !== null &&
@@ -32,14 +43,73 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
32
43
  ? 'wrapped'
33
44
  : element.installationMode;
34
45
  const componentOwnsSequence = installationMode === 'component-owned-sequence';
46
+ if (componentOwnsSequence &&
47
+ element.initialProps !== null &&
48
+ ['from', 'durationInFrames', 'name'].some((prop) => {
49
+ var _a;
50
+ return Object.hasOwn((_a = element.initialProps) !== null && _a !== void 0 ? _a : {}, prop);
51
+ })) {
52
+ throw new Error('Component-owned Element initial props must not override from, durationInFrames, or name');
53
+ }
54
+ if (componentOwnsSequence &&
55
+ ((_a = element.initialProps) === null || _a === void 0 ? void 0 : _a.style) !== undefined &&
56
+ (element.initialProps.style === null ||
57
+ typeof element.initialProps.style !== 'object' ||
58
+ Array.isArray(element.initialProps.style))) {
59
+ throw new Error('Component-owned Element initial style must be an object');
60
+ }
35
61
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
36
- const plan = await (0, element_install_plan_1.getElementInstallPlan)({
37
- installationName,
38
- destination: {
62
+ let compositionCreation = null;
63
+ let sourceFileOverrides = null;
64
+ if (newComposition !== null) {
65
+ if (newComposition.codemod.newId !== compositionId) {
66
+ throw new Error('New composition ID does not match installation target');
67
+ }
68
+ const registrationFilePath = newComposition.symbolicatedStack
69
+ ? (0, apply_codemod_to_file_1.resolveFilePathFromSymbolicatedStack)(remotionRoot, newComposition.symbolicatedStack)
70
+ : (await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint)).rootFile;
71
+ if (registrationFilePath === null) {
72
+ throw new Error('Cannot find file for composition in project');
73
+ }
74
+ (0, can_update_default_props_1.checkIfTypeScriptFile)(registrationFilePath);
75
+ if (node_path_1.default.resolve(remotionRoot, compositionFile) !== registrationFilePath) {
76
+ throw new Error('New composition source does not match installation target');
77
+ }
78
+ const componentFilePath = node_path_1.default.join(node_path_1.default.dirname(registrationFilePath), `${newComposition.codemod.componentName}.tsx`);
79
+ if ((0, node_fs_1.existsSync)(componentFilePath)) {
80
+ throw new Error(`Cannot create ${node_path_1.default.relative(remotionRoot, componentFilePath)} because it already exists`);
81
+ }
82
+ const registrationFileOldContents = (0, node_fs_1.readFileSync)(registrationFilePath, 'utf-8');
83
+ const registrationFileNewContents = await (0, apply_codemod_to_file_1.applyCodemodToFile)({
84
+ filePath: registrationFilePath,
85
+ codeMod: newComposition.codemod,
86
+ });
87
+ const componentFileContents = await (0, apply_codemod_1.formatNewCompositionFile)(newComposition.codemod);
88
+ compositionCreation = {
89
+ componentFileContents,
90
+ componentFilePath,
91
+ registrationFileNewContents,
92
+ registrationFileOldContents,
93
+ registrationFilePath,
94
+ };
95
+ sourceFileOverrides = new Map([
96
+ [registrationFilePath, registrationFileNewContents],
97
+ [componentFilePath, componentFileContents],
98
+ ]);
99
+ }
100
+ const installDestination = newComposition === null
101
+ ? {
39
102
  type: 'current-composition',
40
103
  compositionFile,
41
104
  compositionId,
42
- },
105
+ }
106
+ : {
107
+ type: 'new-composition',
108
+ compositionFile,
109
+ };
110
+ const plan = await (0, element_install_plan_1.getElementInstallPlan)({
111
+ installationName,
112
+ destination: installDestination,
43
113
  element,
44
114
  entryPoint,
45
115
  remotionRoot,
@@ -76,8 +146,13 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
76
146
  },
77
147
  };
78
148
  }
149
+ if (compositionCreation !== null &&
150
+ plan.elementFileName ===
151
+ node_path_1.default.join(node_path_1.default.dirname(plan.safePaths.compositionFileName), node_path_1.default.basename(compositionCreation.componentFilePath))) {
152
+ throw new Error('Element source file conflicts with the new composition file');
153
+ }
79
154
  const shouldWriteElementFile = !plan.elementFileExists || elementSourcesDiffer;
80
- const inserted = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
155
+ const insertionInput = {
81
156
  remotionRoot,
82
157
  compositionFile,
83
158
  compositionId,
@@ -86,19 +161,20 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
86
161
  componentName: plan.componentName,
87
162
  importName: plan.componentName,
88
163
  importPath: plan.importPath,
89
- props: componentOwnsSequence
90
- ? [
91
- ...(element.durationInFrames === null
92
- ? []
93
- : [
94
- {
95
- name: 'durationInFrames',
96
- value: element.durationInFrames,
97
- },
98
- ]),
99
- { name: 'name', value: element.displayName },
100
- ]
101
- : [],
164
+ props: [
165
+ ...Object.entries((_d = element.initialProps) !== null && _d !== void 0 ? _d : {}).map(([name, value]) => ({ name, value })),
166
+ ...(componentOwnsSequence && element.durationInFrames !== null
167
+ ? [
168
+ {
169
+ name: 'durationInFrames',
170
+ value: element.durationInFrames,
171
+ },
172
+ ]
173
+ : []),
174
+ ...(componentOwnsSequence
175
+ ? [{ name: 'name', value: element.displayName }]
176
+ : []),
177
+ ],
102
178
  position: componentOwnsSequence ? position : null,
103
179
  },
104
180
  from: componentOwnsSequence ? from : null,
@@ -112,14 +188,18 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
112
188
  name: element.displayName,
113
189
  position,
114
190
  },
191
+ };
192
+ const inserted = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
193
+ ...insertionInput,
194
+ sourceFileOverrides,
115
195
  });
196
+ if (compositionCreation !== null &&
197
+ inserted.fileName !== compositionCreation.componentFilePath) {
198
+ throw new Error('New composition component does not match installation target');
199
+ }
116
200
  const finalPlan = await (0, element_install_plan_1.getElementInstallPlan)({
117
201
  installationName,
118
- destination: {
119
- type: 'current-composition',
120
- compositionFile,
121
- compositionId,
122
- },
202
+ destination: installDestination,
123
203
  element,
124
204
  entryPoint,
125
205
  remotionRoot,
@@ -134,6 +214,12 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
134
214
  })) {
135
215
  throw new Error('Element source changed during installation');
136
216
  }
217
+ if (compositionCreation !== null &&
218
+ ((0, node_fs_1.readFileSync)(compositionCreation.registrationFilePath, 'utf-8') !==
219
+ compositionCreation.registrationFileOldContents ||
220
+ (0, node_fs_1.existsSync)(compositionCreation.componentFilePath))) {
221
+ throw new Error('Composition source changed during Element installation');
222
+ }
137
223
  const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([
138
224
  {
139
225
  absolutePath: inserted.fileName,
@@ -142,6 +228,17 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
142
228
  ], null);
143
229
  (0, undo_stack_1.pushTransactionToUndoStack)({
144
230
  snapshots: [
231
+ ...(compositionCreation === null
232
+ ? []
233
+ : [
234
+ {
235
+ filePath: compositionCreation.registrationFilePath,
236
+ oldContents: compositionCreation.registrationFileOldContents,
237
+ newContents: compositionCreation.registrationFileNewContents,
238
+ logLine: (_e = (_b = newComposition === null || newComposition === void 0 ? void 0 : newComposition.symbolicatedStack) === null || _b === void 0 ? void 0 : _b.originalLineNumber) !== null && _e !== void 0 ? _e : 1,
239
+ nodePathRemappings: null,
240
+ },
241
+ ]),
145
242
  ...(shouldWriteElementFile
146
243
  ? [
147
244
  {
@@ -155,7 +252,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
155
252
  : []),
156
253
  {
157
254
  filePath: inserted.fileName,
158
- oldContents: inserted.oldContents,
255
+ oldContents: compositionCreation === null ? inserted.oldContents : null,
159
256
  newContents: inserted.output,
160
257
  logLine: inserted.logLine,
161
258
  nodePathRemappings: inserted.nodePathRemappings,
@@ -163,17 +260,34 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
163
260
  ],
164
261
  logLevel,
165
262
  remotionRoot,
166
- description: {
167
- undoMessage: `↩️ Added ${element.displayName}`,
168
- redoMessage: `↪️ Added ${element.displayName}`,
169
- },
263
+ description: newComposition === null
264
+ ? {
265
+ undoMessage: `↩️ Added ${element.displayName}`,
266
+ redoMessage: `↪️ Added ${element.displayName}`,
267
+ }
268
+ : {
269
+ undoMessage: `↩️ Installation of ${element.displayName} into composition "${compositionId}"`,
270
+ redoMessage: `↪️ Installation of ${element.displayName} into composition "${compositionId}"`,
271
+ },
170
272
  entryType: 'insert-jsx-element',
171
273
  suppressHmrOnFileRestore: false,
274
+ undoRedoNavigation,
172
275
  });
276
+ if (compositionCreation !== null) {
277
+ (0, undo_stack_1.suppressUndoStackInvalidation)(compositionCreation.registrationFilePath);
278
+ }
173
279
  if (shouldWriteElementFile) {
174
280
  (0, undo_stack_1.suppressUndoStackInvalidation)(plan.elementFileName);
175
281
  }
176
282
  (0, undo_stack_1.suppressUndoStackInvalidation)(inserted.fileName);
283
+ if (compositionCreation !== null) {
284
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
285
+ file: compositionCreation.registrationFilePath,
286
+ content: compositionCreation.registrationFileNewContents,
287
+ originatorClientId: undefined,
288
+ metadata: null,
289
+ });
290
+ }
177
291
  if (shouldWriteElementFile) {
178
292
  (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
179
293
  file: plan.elementFileName,
@@ -188,6 +302,13 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
188
302
  originatorClientId: undefined,
189
303
  metadata: { skipSequencePropsUpdate: true },
190
304
  });
305
+ if (newComposition !== null && compositionCreation !== null) {
306
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright((0, format_log_file_location_1.formatLogFileLocation)({
307
+ remotionRoot,
308
+ absolutePath: compositionCreation.registrationFilePath,
309
+ line: (_f = (_c = newComposition.symbolicatedStack) === null || _c === void 0 ? void 0 : _c.originalLineNumber) !== null && _f !== void 0 ? _f : 1,
310
+ }))} Created composition "${compositionId}"`);
311
+ }
191
312
  const compositionLocationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
192
313
  remotionRoot,
193
314
  absolutePath: inserted.fileName,
@@ -165,6 +165,7 @@ const insertJsxElementHandler = ({ input: { compositionFile, compositionId, elem
165
165
  element,
166
166
  from,
167
167
  prettierConfigOverride: null,
168
+ sourceFileOverrides: null,
168
169
  });
169
170
  const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([
170
171
  {
@@ -0,0 +1,4 @@
1
+ import type { GetRemotionSkillsInfoResponse, InstallRemotionSkillRequest, RemoveRemotionSkillRequest } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const installRemotionSkillHandler: ApiHandler<InstallRemotionSkillRequest, GetRemotionSkillsInfoResponse>;
4
+ export declare const removeRemotionSkillHandler: ApiHandler<RemoveRemotionSkillRequest, GetRemotionSkillsInfoResponse>;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeRemotionSkillHandler = exports.installRemotionSkillHandler = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const renderer_1 = require("@remotion/renderer");
6
+ const package_manager_spawn_options_1 = require("../../helpers/package-manager-spawn-options");
7
+ const remotion_skill_names_1 = require("../../remotion-skill-names");
8
+ const get_package_manager_1 = require("../get-package-manager");
9
+ const remotion_skills_info_1 = require("./remotion-skills-info");
10
+ const changingSkillsInProjects = new Set();
11
+ const changeRemotionSkill = async ({ action, remotionRoot, input: { skill }, logLevel, }) => {
12
+ if (!remotion_skill_names_1.remotionSkillNames.some((name) => name === skill)) {
13
+ throw new Error(`Unknown Remotion skill: ${JSON.stringify(skill)}`);
14
+ }
15
+ if (changingSkillsInProjects.has(remotionRoot)) {
16
+ throw new Error('A skill is already being installed or removed. Please try again once it finishes.');
17
+ }
18
+ changingSkillsInProjects.add(remotionRoot);
19
+ try {
20
+ const installedSkill = (0, remotion_skills_info_1.getRemotionSkillsInfo)({ remotionRoot }).skills.find(({ name }) => name === skill);
21
+ const removingGlobally = action === 'remove' &&
22
+ (installedSkill === null || installedSkill === void 0 ? void 0 : installedSkill.installedInProject) === false &&
23
+ installedSkill.installedGlobally;
24
+ if (action === 'remove' &&
25
+ !removingGlobally &&
26
+ !(installedSkill === null || installedSkill === void 0 ? void 0 : installedSkill.installedInProject)) {
27
+ throw new Error(`${skill} is not installed.`);
28
+ }
29
+ const packageManager = (0, get_package_manager_1.getPackageManager)({
30
+ remotionRoot,
31
+ packageManager: undefined,
32
+ dirUp: 0,
33
+ logLevel,
34
+ });
35
+ const useBunx = packageManager !== 'unknown' && packageManager.manager === 'bun';
36
+ const executable = useBunx
37
+ ? 'bunx'
38
+ : process.platform === 'win32'
39
+ ? 'npx.cmd'
40
+ : 'npx';
41
+ const commandArgs = action === 'install'
42
+ ? ['add', `remotion-dev/skills@${skill}`, '--yes']
43
+ : ['remove', ...(removingGlobally ? ['--global'] : []), skill, '--yes'];
44
+ const args = useBunx
45
+ ? ['--silent', 'skills@1.5.26', ...commandArgs]
46
+ : ['--yes', '--loglevel=error', 'skills@1.5.26', ...commandArgs];
47
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray(`╭─ ${executable} ${args.join(' ')}`));
48
+ const time = Date.now();
49
+ try {
50
+ await new Promise((resolve, reject) => {
51
+ const child = (0, node_child_process_1.spawn)(executable, args, {
52
+ cwd: remotionRoot,
53
+ env: { ...process.env, DISABLE_TELEMETRY: '1' },
54
+ stdio: ['ignore', 'pipe', 'pipe'],
55
+ ...(0, package_manager_spawn_options_1.getPackageManagerSpawnOptions)(),
56
+ });
57
+ let output = '';
58
+ const onData = (data) => {
59
+ output = (output + data.toString()).slice(-8000);
60
+ data
61
+ .toString()
62
+ .trim()
63
+ .split('\n')
64
+ .forEach((line) => renderer_1.RenderInternals.Log.info({ indent: true, logLevel }, line));
65
+ };
66
+ child.stdout.on('data', onData);
67
+ child.stderr.on('data', onData);
68
+ child.on('error', reject);
69
+ child.on('close', (code, signal) => {
70
+ if (code === 0) {
71
+ resolve();
72
+ }
73
+ else {
74
+ reject(new Error(`Could not ${action} ${skill} (exit code ${code}, signal ${signal}). ${output.trim()}`));
75
+ }
76
+ });
77
+ });
78
+ const info = (0, remotion_skills_info_1.getRemotionSkillsInfo)({ remotionRoot });
79
+ const updatedSkill = info.skills.find(({ name }) => name === skill);
80
+ if (action === 'install' && !(updatedSkill === null || updatedSkill === void 0 ? void 0 : updatedSkill.installedInProject)) {
81
+ throw new Error(`The installer finished, but ${skill} was not found in the project. Please try again.`);
82
+ }
83
+ if (action === 'remove' &&
84
+ (removingGlobally
85
+ ? updatedSkill === null || updatedSkill === void 0 ? void 0 : updatedSkill.installedGlobally
86
+ : updatedSkill === null || updatedSkill === void 0 ? void 0 : updatedSkill.installedInProject)) {
87
+ throw new Error(`The remover finished, but ${skill} is still installed ${removingGlobally ? 'globally' : 'in the project'}. Please try again.`);
88
+ }
89
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray('╰─ '), `Done in ${Date.now() - time}ms`);
90
+ return info;
91
+ }
92
+ catch (error) {
93
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.gray('╰─ '), renderer_1.RenderInternals.chalk.red(`Errored in ${Date.now() - time}ms`));
94
+ throw error;
95
+ }
96
+ }
97
+ finally {
98
+ changingSkillsInProjects.delete(remotionRoot);
99
+ }
100
+ };
101
+ const installRemotionSkillHandler = (input) => {
102
+ return changeRemotionSkill({ ...input, action: 'install' });
103
+ };
104
+ exports.installRemotionSkillHandler = installRemotionSkillHandler;
105
+ const removeRemotionSkillHandler = (input) => {
106
+ return changeRemotionSkill({ ...input, action: 'remove' });
107
+ };
108
+ exports.removeRemotionSkillHandler = removeRemotionSkillHandler;
@@ -0,0 +1,3 @@
1
+ import type { ApiRoutes } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const invalidateBundleHandler: ApiHandler<ApiRoutes['/api/invalidate-bundle']['Request'], ApiRoutes['/api/invalidate-bundle']['Response']>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.invalidateBundleHandler = void 0;
4
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
5
+ const source_file_write_queue_1 = require("./source-file-write-queue");
6
+ const invalidateBundleHandler = () => {
7
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
8
+ return { didInvalidate: await (0, watch_ignore_next_change_1.invalidatePreviouslySuppressedFiles)() };
9
+ });
10
+ };
11
+ exports.invalidateBundleHandler = invalidateBundleHandler;
@@ -195,6 +195,7 @@ const moveKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, rem
195
195
  ? 'sequence-props'
196
196
  : 'effect-props',
197
197
  suppressHmrOnFileRestore: true,
198
+ undoRedoNavigation: null,
198
199
  });
199
200
  for (const snapshot of snapshots) {
200
201
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
@@ -99,6 +99,7 @@ const saveMultipleEffectPropsHandler = ({ input: { edits, clientId, undoLabel, r
99
99
  },
100
100
  entryType: 'effect-props',
101
101
  suppressHmrOnFileRestore: true,
102
+ undoRedoNavigation: null,
102
103
  });
103
104
  for (const [absolutePath, output] of outputByPath) {
104
105
  (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
@@ -401,6 +401,7 @@ const saveSequencePropsHandler = ({ input: { edits, addedKeyframes, movedKeyfram
401
401
  description: { undoMessage, redoMessage },
402
402
  entryType: 'sequence-props',
403
403
  suppressHmrOnFileRestore: suppressHmr,
404
+ undoRedoNavigation: null,
404
405
  });
405
406
  for (const [absolutePath, output] of outputByPath) {
406
407
  (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
@@ -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.headers.origin);
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.headers.origin);
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
- installationMode: (_b = element.installationMode) !== null && _b !== void 0 ? _b : null,
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.headers.origin);
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.headers.origin);
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: (origin: string | undefined) => string | null;
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>;