@remotion/studio-server 4.0.527 → 4.0.528

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 (47) hide show
  1. package/dist/codemods/apply-codemod-to-file.d.ts +2 -1
  2. package/dist/codemods/apply-codemod-to-file.js +141 -8
  3. package/dist/codemods/update-effect-props/update-effect-props.d.ts +6 -33
  4. package/dist/codemods/update-effect-props/update-effect-props.js +16 -6
  5. package/dist/codemods/update-keyframes/update-keyframes.d.ts +24 -65
  6. package/dist/codemods/update-keyframes/update-keyframes.js +23 -5
  7. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +2 -17
  8. package/dist/codemods/update-sequence-props/update-sequence-props.js +15 -8
  9. package/dist/helpers/open-file-for-writing-without-symlinks.d.ts +6 -1
  10. package/dist/helpers/open-file-for-writing-without-symlinks.js +9 -6
  11. package/dist/index.d.ts +0 -22
  12. package/dist/index.js +0 -7
  13. package/dist/preview-server/api-routes.js +4 -0
  14. package/dist/preview-server/hot-middleware/index.js +13 -46
  15. package/dist/preview-server/routes/add-effect.js +16 -8
  16. package/dist/preview-server/routes/apply-codemod.d.ts +0 -19
  17. package/dist/preview-server/routes/apply-codemod.js +22 -25
  18. package/dist/preview-server/routes/apply-visual-control-change.js +12 -65
  19. package/dist/preview-server/routes/can-update-sequence-props.d.ts +0 -10
  20. package/dist/preview-server/routes/can-update-sequence-props.js +39 -505
  21. package/dist/preview-server/routes/delete-effect.js +14 -13
  22. package/dist/preview-server/routes/delete-jsx-nodes.js +15 -4
  23. package/dist/preview-server/routes/download-remote-asset.d.ts +5 -0
  24. package/dist/preview-server/routes/download-remote-asset.js +25 -20
  25. package/dist/preview-server/routes/duplicate-effect.js +11 -4
  26. package/dist/preview-server/routes/duplicate-jsx-node.js +14 -4
  27. package/dist/preview-server/routes/insert-element.js +399 -280
  28. package/dist/preview-server/routes/install-dependency.js +14 -4
  29. package/dist/preview-server/routes/prepare-element-install.js +3 -0
  30. package/dist/preview-server/routes/reorder-effect.js +11 -5
  31. package/dist/preview-server/routes/reorder-sequence.js +9 -5
  32. package/dist/preview-server/routes/replace-video-source.d.ts +3 -0
  33. package/dist/preview-server/routes/replace-video-source.js +81 -0
  34. package/dist/preview-server/routes/save-sequence-props.js +5 -26
  35. package/dist/preview-server/routes/split-jsx-sequence.js +13 -5
  36. package/dist/preview-server/routes/split-video-from-audio.js +8 -4
  37. package/dist/preview-server/routes/subscribe-to-sequence-props.js +6 -10
  38. package/dist/preview-server/routes/update-config.js +38 -2
  39. package/dist/preview-server/routes/update-default-props.js +11 -8
  40. package/dist/preview-server/routes/wrap-jsx-node.d.ts +3 -0
  41. package/dist/preview-server/routes/wrap-jsx-node.js +97 -0
  42. package/dist/preview-server/studio-protocol/handle-discovery.js +1 -1
  43. package/dist/preview-server/studio-protocol/handle-element-library.js +3 -3
  44. package/dist/preview-server/undo-stack.d.ts +2 -1
  45. package/dist/preview-server/undo-stack.js +19 -0
  46. package/dist/routes.js +2 -0
  47. package/package.json +8 -8
@@ -7,15 +7,17 @@ exports.insertElementHandler = 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
+ const studio_protocol_1 = require("@remotion/studio-protocol");
10
11
  const apply_codemod_to_file_1 = require("../../codemods/apply-codemod-to-file");
11
12
  const file_watcher_1 = require("../../file-watcher");
13
+ const open_file_for_writing_without_symlinks_1 = require("../../helpers/open-file-for-writing-without-symlinks");
12
14
  const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
13
15
  const format_log_file_location_1 = require("../format-log-file-location");
14
16
  const project_info_1 = require("../project-info");
15
17
  const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
16
18
  const undo_stack_1 = require("../undo-stack");
17
- const apply_codemod_1 = require("./apply-codemod");
18
19
  const can_update_default_props_1 = require("./can-update-default-props");
20
+ const download_remote_asset_1 = require("./download-remote-asset");
19
21
  const element_install_plan_1 = require("./element-install-plan");
20
22
  const source_file_write_queue_1 = require("./source-file-write-queue");
21
23
  const hasExpectedFileState = ({ expected, actual, }) => {
@@ -30,312 +32,429 @@ const hasExpectedFileState = ({ expected, actual, }) => {
30
32
  }
31
33
  return actual.sourceHash === expected.sourceHash;
32
34
  };
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;
35
+ const insertElementHandler = async ({ input: { compositionFile, compositionId, element, installationName, expectedFileState, from, position, overwriteExisting, undoRedoNavigation, newComposition, }, entryPoint, remotionRoot, logLevel, publicDir, }) => {
36
+ var _a;
37
+ let resolvedAssets;
36
38
  try {
37
- (0, element_install_plan_1.validateElementInstallPosition)(position);
38
- if (from !== null &&
39
- (!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
40
- throw new Error('from must be a non-negative integer');
41
- }
42
- const installationMode = element.installationMode === null
43
- ? 'wrapped'
44
- : element.installationMode;
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
- }
61
- renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
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');
39
+ studio_protocol_1.StudioProtocolInternals.assertElementAssets(element.assets);
40
+ studio_protocol_1.StudioProtocolInternals.assertElementAssetReferences(element);
41
+ resolvedAssets = await studio_protocol_1.StudioProtocolInternals.resolveElementAssets({
42
+ assets: element.assets,
43
+ downloadAsset: (options) => (0, download_remote_asset_1.downloadRemoteAssetBytes)({ ...options, acceptHeader: null }),
44
+ });
45
+ }
46
+ catch (err) {
47
+ return {
48
+ success: false,
49
+ type: 'error',
50
+ reason: err.message,
51
+ stack: (_a = err.stack) !== null && _a !== void 0 ? _a : '',
52
+ };
53
+ }
54
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
55
+ var _a, _b, _c, _d, _e;
56
+ var _f, _g, _h, _j;
57
+ const createdAssets = [];
58
+ const changedSources = [];
59
+ let undoEntryPushed = false;
60
+ try {
61
+ (0, element_install_plan_1.validateElementInstallPosition)(position);
62
+ if (from !== null &&
63
+ (!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
64
+ throw new Error('from must be a non-negative integer');
67
65
  }
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');
66
+ const installationMode = element.installationMode === null
67
+ ? 'wrapped'
68
+ : element.installationMode;
69
+ const componentOwnsSequence = installationMode === 'component-owned-sequence';
70
+ if (componentOwnsSequence &&
71
+ element.initialProps !== null &&
72
+ ['from', 'durationInFrames', 'name'].some((prop) => {
73
+ var _a;
74
+ return Object.hasOwn((_a = element.initialProps) !== null && _a !== void 0 ? _a : {}, prop);
75
+ })) {
76
+ throw new Error('Component-owned Element initial props must not override from, durationInFrames, or name');
73
77
  }
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');
78
+ if (componentOwnsSequence &&
79
+ ((_a = element.initialProps) === null || _a === void 0 ? void 0 : _a.style) !== undefined &&
80
+ (element.initialProps.style === null ||
81
+ typeof element.initialProps.style !== 'object' ||
82
+ Array.isArray(element.initialProps.style))) {
83
+ throw new Error('Component-owned Element initial style must be an object');
77
84
  }
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`);
85
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.slug}"`);
86
+ let compositionCreation = null;
87
+ let sourceFileOverrides = null;
88
+ if (newComposition !== null) {
89
+ if (newComposition.codemod.newId !== compositionId) {
90
+ throw new Error('New composition ID does not match installation target');
91
+ }
92
+ const registrationFilePath = newComposition.symbolicatedStack
93
+ ? (0, apply_codemod_to_file_1.resolveFilePathFromSymbolicatedStack)(remotionRoot, newComposition.symbolicatedStack)
94
+ : (await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint)).rootFile;
95
+ if (registrationFilePath === null) {
96
+ throw new Error('Cannot find file for composition in project');
97
+ }
98
+ (0, can_update_default_props_1.checkIfTypeScriptFile)(registrationFilePath);
99
+ if (node_path_1.default.resolve(remotionRoot, compositionFile) !== registrationFilePath) {
100
+ throw new Error('New composition source does not match installation target');
101
+ }
102
+ const componentFilePath = node_path_1.default.join(node_path_1.default.dirname(registrationFilePath), `${newComposition.codemod.componentName}.tsx`);
103
+ if ((0, node_fs_1.existsSync)(componentFilePath)) {
104
+ throw new Error(`Cannot create ${node_path_1.default.relative(remotionRoot, componentFilePath)} because it already exists`);
105
+ }
106
+ const registrationFileOldContents = (0, node_fs_1.readFileSync)(registrationFilePath, 'utf-8');
107
+ const codemodResult = await (0, apply_codemod_to_file_1.applyCodemodToFile)({
108
+ filePath: registrationFilePath,
109
+ codeMod: newComposition.codemod,
110
+ });
111
+ const registrationFileNewContents = (_f = (_b = codemodResult.changes.find((change) => change.filePath === registrationFilePath)) === null || _b === void 0 ? void 0 : _b.nextContents) !== null && _f !== void 0 ? _f : registrationFileOldContents;
112
+ const componentFileContents = (_c = codemodResult.changes.find((change) => change.filePath === componentFilePath)) === null || _c === void 0 ? void 0 : _c.nextContents;
113
+ if (componentFileContents === null ||
114
+ componentFileContents === undefined) {
115
+ throw new Error('Could not create the composition component');
116
+ }
117
+ compositionCreation = {
118
+ componentFileContents,
119
+ componentFilePath,
120
+ registrationFileNewContents,
121
+ registrationFileOldContents,
122
+ registrationFilePath,
123
+ };
124
+ sourceFileOverrides = new Map([
125
+ [registrationFilePath, registrationFileNewContents],
126
+ [componentFilePath, componentFileContents],
127
+ ]);
81
128
  }
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,
129
+ const installDestination = newComposition === null
130
+ ? {
131
+ type: 'current-composition',
132
+ compositionFile,
133
+ compositionId,
134
+ }
135
+ : {
136
+ type: 'new-composition',
137
+ compositionFile,
138
+ };
139
+ const plan = await (0, element_install_plan_1.getElementInstallPlan)({
140
+ installationName,
141
+ destination: installDestination,
142
+ element,
143
+ entryPoint,
144
+ remotionRoot,
86
145
  });
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
- ? {
102
- type: 'current-composition',
103
- compositionFile,
104
- compositionId,
146
+ if (expectedFileState !== null &&
147
+ !hasExpectedFileState({
148
+ actual: plan.expectedFileState,
149
+ expected: expectedFileState,
150
+ })) {
151
+ const { existingElementSource } = plan;
152
+ if (existingElementSource !== null) {
153
+ return {
154
+ success: false,
155
+ type: 'file-conflict',
156
+ conflict: {
157
+ filePath: plan.filePath,
158
+ existingSource: existingElementSource,
159
+ incomingSource: element.sourceCode,
160
+ },
161
+ };
162
+ }
163
+ throw new Error('Element source changed during installation');
105
164
  }
106
- : {
107
- type: 'new-composition',
108
- compositionFile,
109
- };
110
- const plan = await (0, element_install_plan_1.getElementInstallPlan)({
111
- installationName,
112
- destination: installDestination,
113
- element,
114
- entryPoint,
115
- remotionRoot,
116
- });
117
- if (expectedFileState !== null &&
118
- !hasExpectedFileState({
119
- actual: plan.expectedFileState,
120
- expected: expectedFileState,
121
- })) {
122
- const { existingElementSource } = plan;
123
- if (existingElementSource !== null) {
165
+ const elementSourcesDiffer = plan.existingElementSource !== null &&
166
+ plan.existingElementSource !== element.sourceCode;
167
+ if (!overwriteExisting && plan.existingElementSource !== null) {
124
168
  return {
125
169
  success: false,
126
170
  type: 'file-conflict',
127
171
  conflict: {
128
172
  filePath: plan.filePath,
129
- existingSource: existingElementSource,
173
+ existingSource: plan.existingElementSource,
130
174
  incomingSource: element.sourceCode,
131
175
  },
132
176
  };
133
177
  }
134
- throw new Error('Element source changed during installation');
135
- }
136
- const elementSourcesDiffer = plan.existingElementSource !== null &&
137
- plan.existingElementSource !== element.sourceCode;
138
- if (!overwriteExisting && plan.existingElementSource !== null) {
139
- return {
140
- success: false,
141
- type: 'file-conflict',
142
- conflict: {
143
- filePath: plan.filePath,
144
- existingSource: plan.existingElementSource,
145
- incomingSource: element.sourceCode,
178
+ if (compositionCreation !== null &&
179
+ plan.elementFileName ===
180
+ node_path_1.default.join(node_path_1.default.dirname(plan.safePaths.compositionFileName), node_path_1.default.basename(compositionCreation.componentFilePath))) {
181
+ throw new Error('Element source file conflicts with the new composition file');
182
+ }
183
+ const shouldWriteElementFile = !plan.elementFileExists || elementSourcesDiffer;
184
+ const insertionInput = {
185
+ remotionRoot,
186
+ compositionFile,
187
+ compositionId,
188
+ element: {
189
+ type: 'component',
190
+ componentName: plan.componentName,
191
+ importName: plan.componentName,
192
+ importPath: plan.importPath,
193
+ props: [
194
+ ...Object.entries((_g = element.initialProps) !== null && _g !== void 0 ? _g : {}).map(([name, value]) => ({ name, value })),
195
+ ...(componentOwnsSequence && element.durationInFrames !== null
196
+ ? [
197
+ {
198
+ name: 'durationInFrames',
199
+ value: element.durationInFrames,
200
+ },
201
+ ]
202
+ : []),
203
+ ...(componentOwnsSequence
204
+ ? [{ name: 'name', value: element.displayName }]
205
+ : []),
206
+ ],
207
+ position: componentOwnsSequence ? position : null,
146
208
  },
209
+ from: componentOwnsSequence ? from : null,
210
+ prettierConfigOverride: null,
211
+ wrapInSequence: componentOwnsSequence
212
+ ? null
213
+ : {
214
+ dimensions: element.dimensions,
215
+ durationInFrames: element.durationInFrames,
216
+ from,
217
+ name: element.displayName,
218
+ position,
219
+ },
147
220
  };
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
- }
154
- const shouldWriteElementFile = !plan.elementFileExists || elementSourcesDiffer;
155
- const insertionInput = {
156
- remotionRoot,
157
- compositionFile,
158
- compositionId,
159
- element: {
160
- type: 'component',
161
- componentName: plan.componentName,
162
- importName: plan.componentName,
163
- importPath: plan.importPath,
164
- props: [
165
- ...Object.entries((_d = element.initialProps) !== null && _d !== void 0 ? _d : {}).map(([name, value]) => ({ name, value })),
166
- ...(componentOwnsSequence && element.durationInFrames !== null
221
+ const inserted = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
222
+ ...insertionInput,
223
+ sourceFileOverrides,
224
+ });
225
+ if (compositionCreation !== null &&
226
+ inserted.fileName !== compositionCreation.componentFilePath) {
227
+ throw new Error('New composition component does not match installation target');
228
+ }
229
+ const finalPlan = await (0, element_install_plan_1.getElementInstallPlan)({
230
+ installationName,
231
+ destination: installDestination,
232
+ element,
233
+ entryPoint,
234
+ remotionRoot,
235
+ });
236
+ if (finalPlan.safePaths.compositionFileName !==
237
+ plan.safePaths.compositionFileName) {
238
+ throw new Error('Composition source changed during Element installation');
239
+ }
240
+ if (!hasExpectedFileState({
241
+ actual: finalPlan.expectedFileState,
242
+ expected: plan.expectedFileState,
243
+ })) {
244
+ throw new Error('Element source changed during installation');
245
+ }
246
+ if (compositionCreation !== null &&
247
+ ((0, node_fs_1.readFileSync)(compositionCreation.registrationFilePath, 'utf-8') !==
248
+ compositionCreation.registrationFileOldContents ||
249
+ (0, node_fs_1.existsSync)(compositionCreation.componentFilePath))) {
250
+ throw new Error('Composition source changed during Element installation');
251
+ }
252
+ const assetsToCreate = [];
253
+ for (const asset of resolvedAssets) {
254
+ const absolutePath = node_path_1.default.resolve(publicDir, ...asset.path.split('/'));
255
+ (0, open_file_for_writing_without_symlinks_1.assertNoSymlinks)({
256
+ absolutePath,
257
+ rootDirectory: node_path_1.default.resolve(publicDir),
258
+ });
259
+ if ((0, node_fs_1.existsSync)(absolutePath)) {
260
+ if (!(0, node_fs_1.lstatSync)(absolutePath).isFile()) {
261
+ throw new Error(`Asset ${asset.path} already exists and is not a file`);
262
+ }
263
+ if (!(0, node_fs_1.readFileSync)(absolutePath).equals(asset.contents)) {
264
+ throw new Error(`Asset ${asset.path} already exists with different contents`);
265
+ }
266
+ }
267
+ else {
268
+ assetsToCreate.push({ absolutePath, contents: asset.contents });
269
+ }
270
+ }
271
+ for (const asset of assetsToCreate) {
272
+ const fileDescriptor = (0, open_file_for_writing_without_symlinks_1.openFileForWritingWithoutSymlinks)({
273
+ absolutePath: asset.absolutePath,
274
+ exclusive: true,
275
+ rootDirectory: publicDir,
276
+ });
277
+ try {
278
+ (0, node_fs_1.writeFileSync)(fileDescriptor, asset.contents);
279
+ }
280
+ catch (error) {
281
+ (0, node_fs_1.closeSync)(fileDescriptor);
282
+ try {
283
+ (0, node_fs_1.unlinkSync)(asset.absolutePath);
284
+ }
285
+ catch (_k) {
286
+ // Keep the original write error.
287
+ }
288
+ throw error;
289
+ }
290
+ (0, node_fs_1.closeSync)(fileDescriptor);
291
+ createdAssets.push(asset);
292
+ }
293
+ const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([
294
+ {
295
+ absolutePath: inserted.fileName,
296
+ remappings: inserted.nodePathRemappings,
297
+ },
298
+ ], null);
299
+ const writeSource = ({ content, file, metadata, }) => {
300
+ const oldContents = (0, node_fs_1.existsSync)(file)
301
+ ? (0, node_fs_1.readFileSync)(file, 'utf8')
302
+ : null;
303
+ changedSources.push({
304
+ filePath: file,
305
+ newContents: content,
306
+ oldContents,
307
+ });
308
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
309
+ file,
310
+ content,
311
+ originatorClientId: undefined,
312
+ metadata,
313
+ });
314
+ };
315
+ (0, undo_stack_1.pushTransactionToUndoStack)({
316
+ snapshots: [
317
+ ...(compositionCreation === null
318
+ ? []
319
+ : [
320
+ {
321
+ filePath: compositionCreation.registrationFilePath,
322
+ oldContents: compositionCreation.registrationFileOldContents,
323
+ newContents: compositionCreation.registrationFileNewContents,
324
+ logLine: (_h = (_d = newComposition === null || newComposition === void 0 ? void 0 : newComposition.symbolicatedStack) === null || _d === void 0 ? void 0 : _d.originalLineNumber) !== null && _h !== void 0 ? _h : 1,
325
+ nodePathRemappings: null,
326
+ },
327
+ ]),
328
+ ...(shouldWriteElementFile
167
329
  ? [
168
330
  {
169
- name: 'durationInFrames',
170
- value: element.durationInFrames,
331
+ filePath: plan.elementFileName,
332
+ oldContents: plan.existingElementSource,
333
+ newContents: element.sourceCode,
334
+ logLine: 1,
335
+ nodePathRemappings: null,
171
336
  },
172
337
  ]
173
338
  : []),
174
- ...(componentOwnsSequence
175
- ? [{ name: 'name', value: element.displayName }]
176
- : []),
339
+ {
340
+ filePath: inserted.fileName,
341
+ oldContents: compositionCreation === null ? inserted.oldContents : null,
342
+ newContents: inserted.output,
343
+ logLine: inserted.logLine,
344
+ nodePathRemappings: inserted.nodePathRemappings,
345
+ },
177
346
  ],
178
- position: componentOwnsSequence ? position : null,
179
- },
180
- from: componentOwnsSequence ? from : null,
181
- prettierConfigOverride: null,
182
- wrapInSequence: componentOwnsSequence
183
- ? null
184
- : {
185
- dimensions: element.dimensions,
186
- durationInFrames: element.durationInFrames,
187
- from,
188
- name: element.displayName,
189
- position,
190
- },
191
- };
192
- const inserted = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
193
- ...insertionInput,
194
- sourceFileOverrides,
195
- });
196
- if (compositionCreation !== null &&
197
- inserted.fileName !== compositionCreation.componentFilePath) {
198
- throw new Error('New composition component does not match installation target');
199
- }
200
- const finalPlan = await (0, element_install_plan_1.getElementInstallPlan)({
201
- installationName,
202
- destination: installDestination,
203
- element,
204
- entryPoint,
205
- remotionRoot,
206
- });
207
- if (finalPlan.safePaths.compositionFileName !==
208
- plan.safePaths.compositionFileName) {
209
- throw new Error('Composition source changed during Element installation');
210
- }
211
- if (!hasExpectedFileState({
212
- actual: finalPlan.expectedFileState,
213
- expected: plan.expectedFileState,
214
- })) {
215
- throw new Error('Element source changed during installation');
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
- }
223
- const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([
224
- {
347
+ logLevel,
348
+ remotionRoot,
349
+ description: newComposition === null
350
+ ? {
351
+ undoMessage: `↩️ Added ${element.displayName}`,
352
+ redoMessage: `↪️ Added ${element.displayName}`,
353
+ }
354
+ : {
355
+ undoMessage: `↩️ Installation of ${element.displayName} into composition "${compositionId}"`,
356
+ redoMessage: `↪️ Installation of ${element.displayName} into composition "${compositionId}"`,
357
+ },
358
+ entryType: 'insert-jsx-element',
359
+ suppressHmrOnFileRestore: false,
360
+ undoRedoNavigation,
361
+ });
362
+ undoEntryPushed = true;
363
+ if (compositionCreation !== null) {
364
+ (0, undo_stack_1.suppressUndoStackInvalidation)(compositionCreation.registrationFilePath);
365
+ }
366
+ if (shouldWriteElementFile) {
367
+ (0, undo_stack_1.suppressUndoStackInvalidation)(plan.elementFileName);
368
+ }
369
+ (0, undo_stack_1.suppressUndoStackInvalidation)(inserted.fileName);
370
+ if (compositionCreation !== null) {
371
+ writeSource({
372
+ file: compositionCreation.registrationFilePath,
373
+ content: compositionCreation.registrationFileNewContents,
374
+ metadata: null,
375
+ });
376
+ }
377
+ if (shouldWriteElementFile) {
378
+ writeSource({
379
+ file: plan.elementFileName,
380
+ content: element.sourceCode,
381
+ metadata: null,
382
+ });
383
+ }
384
+ writeSource({
385
+ file: inserted.fileName,
386
+ content: inserted.output,
387
+ metadata: { skipSequencePropsUpdate: true },
388
+ });
389
+ if (newComposition !== null && compositionCreation !== null) {
390
+ 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)({
391
+ remotionRoot,
392
+ absolutePath: compositionCreation.registrationFilePath,
393
+ line: (_j = (_e = newComposition.symbolicatedStack) === null || _e === void 0 ? void 0 : _e.originalLineNumber) !== null && _j !== void 0 ? _j : 1,
394
+ }))} Created composition "${compositionId}"`);
395
+ }
396
+ const compositionLocationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
397
+ remotionRoot,
225
398
  absolutePath: inserted.fileName,
226
- remappings: inserted.nodePathRemappings,
227
- },
228
- ], null);
229
- (0, undo_stack_1.pushTransactionToUndoStack)({
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
- ]),
242
- ...(shouldWriteElementFile
243
- ? [
244
- {
245
- filePath: plan.elementFileName,
246
- oldContents: plan.existingElementSource,
247
- newContents: element.sourceCode,
248
- logLine: 1,
249
- nodePathRemappings: null,
250
- },
251
- ]
252
- : []),
253
- {
254
- filePath: inserted.fileName,
255
- oldContents: compositionCreation === null ? inserted.oldContents : null,
256
- newContents: inserted.output,
257
- logLine: inserted.logLine,
258
- nodePathRemappings: inserted.nodePathRemappings,
259
- },
260
- ],
261
- logLevel,
262
- remotionRoot,
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
- },
272
- entryType: 'insert-jsx-element',
273
- suppressHmrOnFileRestore: false,
274
- undoRedoNavigation,
275
- });
276
- if (compositionCreation !== null) {
277
- (0, undo_stack_1.suppressUndoStackInvalidation)(compositionCreation.registrationFilePath);
278
- }
279
- if (shouldWriteElementFile) {
280
- (0, undo_stack_1.suppressUndoStackInvalidation)(plan.elementFileName);
281
- }
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,
399
+ line: inserted.logLine,
289
400
  });
290
- }
291
- if (shouldWriteElementFile) {
292
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
293
- file: plan.elementFileName,
294
- content: element.sourceCode,
295
- originatorClientId: undefined,
296
- metadata: null,
401
+ const elementLocationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
402
+ remotionRoot,
403
+ absolutePath: plan.elementFileName,
404
+ line: 1,
297
405
  });
406
+ const elementFileAction = elementSourcesDiffer
407
+ ? 'Overwrote existing Element source'
408
+ : plan.elementFileExists
409
+ ? 'Reused existing Element source'
410
+ : 'Created Element source';
411
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(elementLocationLabel)} ${elementFileAction}`);
412
+ 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}>`);
413
+ (0, undo_stack_1.printUndoHint)(logLevel);
414
+ return { success: true, nodePathMutation };
298
415
  }
299
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
300
- file: inserted.fileName,
301
- content: inserted.output,
302
- originatorClientId: undefined,
303
- metadata: { skipSequencePropsUpdate: true },
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}"`);
416
+ catch (err) {
417
+ if (undoEntryPushed) {
418
+ (0, undo_stack_1.discardLastUndoEntryAfterFailedCommit)();
419
+ }
420
+ for (const source of changedSources.reverse()) {
421
+ try {
422
+ if ((0, node_fs_1.readFileSync)(source.filePath, 'utf8') !== source.newContents) {
423
+ continue;
424
+ }
425
+ if (source.oldContents === null) {
426
+ (0, node_fs_1.unlinkSync)(source.filePath);
427
+ }
428
+ else {
429
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
430
+ file: source.filePath,
431
+ content: source.oldContents,
432
+ originatorClientId: undefined,
433
+ metadata: null,
434
+ });
435
+ }
436
+ }
437
+ catch (_l) {
438
+ // Preserve subsequent user changes and the original installation error.
439
+ }
440
+ }
441
+ for (const asset of createdAssets.reverse()) {
442
+ try {
443
+ if ((0, node_fs_1.readFileSync)(asset.absolutePath).equals(asset.contents)) {
444
+ (0, node_fs_1.unlinkSync)(asset.absolutePath);
445
+ }
446
+ }
447
+ catch (_m) {
448
+ // Preserve subsequent user changes and the original installation error.
449
+ }
450
+ }
451
+ return {
452
+ success: false,
453
+ type: 'error',
454
+ reason: err.message,
455
+ stack: err.stack,
456
+ };
311
457
  }
312
- const compositionLocationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
313
- remotionRoot,
314
- absolutePath: inserted.fileName,
315
- line: inserted.logLine,
316
- });
317
- const elementLocationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
318
- remotionRoot,
319
- absolutePath: plan.elementFileName,
320
- line: 1,
321
- });
322
- const elementFileAction = elementSourcesDiffer
323
- ? 'Overwrote existing Element source'
324
- : plan.elementFileExists
325
- ? 'Reused existing Element source'
326
- : 'Created Element source';
327
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(elementLocationLabel)} ${elementFileAction}`);
328
- 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}>`);
329
- (0, undo_stack_1.printUndoHint)(logLevel);
330
- return { success: true, nodePathMutation };
331
- }
332
- catch (err) {
333
- return {
334
- success: false,
335
- type: 'error',
336
- reason: err.message,
337
- stack: err.stack,
338
- };
339
- }
340
- });
458
+ });
459
+ };
341
460
  exports.insertElementHandler = insertElementHandler;