@remotion/studio-server 4.0.483 → 4.0.485

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 (36) hide show
  1. package/dist/codemods/recast-mods.js +37 -0
  2. package/dist/codemods/split-jsx-sequence.d.ts +14 -0
  3. package/dist/codemods/split-jsx-sequence.js +345 -0
  4. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +1 -1
  5. package/dist/codemods/update-sequence-props/update-sequence-props.js +62 -7
  6. package/dist/preview-server/api-routes.js +2 -0
  7. package/dist/preview-server/routes/add-effect-keyframe.js +2 -2
  8. package/dist/preview-server/routes/add-effect.js +56 -53
  9. package/dist/preview-server/routes/add-keyframes.js +2 -2
  10. package/dist/preview-server/routes/add-sequence-keyframe.js +2 -2
  11. package/dist/preview-server/routes/apply-codemod.js +104 -101
  12. package/dist/preview-server/routes/apply-visual-control-change.js +83 -80
  13. package/dist/preview-server/routes/can-update-sequence-props.d.ts +13 -1
  14. package/dist/preview-server/routes/can-update-sequence-props.js +101 -7
  15. package/dist/preview-server/routes/delete-effect.js +83 -80
  16. package/dist/preview-server/routes/delete-jsx-node.js +74 -71
  17. package/dist/preview-server/routes/delete-keyframes.js +2 -2
  18. package/dist/preview-server/routes/duplicate-effect.js +77 -74
  19. package/dist/preview-server/routes/duplicate-jsx-node.js +53 -50
  20. package/dist/preview-server/routes/insert-element.js +2 -2
  21. package/dist/preview-server/routes/insert-jsx-element.js +2 -2
  22. package/dist/preview-server/routes/move-keyframes.js +2 -2
  23. package/dist/preview-server/routes/paste-effects.js +59 -56
  24. package/dist/preview-server/routes/reorder-effect.js +55 -52
  25. package/dist/preview-server/routes/reorder-sequence.js +55 -52
  26. package/dist/preview-server/routes/save-effect-props.js +2 -2
  27. package/dist/preview-server/routes/save-sequence-props.js +2 -2
  28. package/dist/preview-server/routes/source-file-write-queue.d.ts +1 -0
  29. package/dist/preview-server/routes/source-file-write-queue.js +11 -0
  30. package/dist/preview-server/routes/split-jsx-sequence.d.ts +3 -0
  31. package/dist/preview-server/routes/split-jsx-sequence.js +66 -0
  32. package/dist/preview-server/routes/update-default-props.js +58 -55
  33. package/dist/preview-server/routes/update-effect-keyframe-settings.js +2 -2
  34. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +2 -2
  35. package/dist/preview-server/undo-stack.d.ts +3 -1
  36. package/package.json +6 -6
@@ -10,59 +10,62 @@ const format_log_file_location_1 = require("../format-log-file-location");
10
10
  const undo_stack_1 = require("../undo-stack");
11
11
  const formatting_1 = require("./log-updates/formatting");
12
12
  const log_update_1 = require("./log-updates/log-update");
13
- const addEffectHandler = async ({ input: { fileName, sequenceNodePath, effectName, effectImportPath, effectConfig, clientId, }, remotionRoot, logLevel, }) => {
14
- try {
15
- renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-effect] Received request for fileName="${fileName}" effect="${effectName}"`);
16
- const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
17
- remotionRoot,
18
- fileName,
19
- action: 'modify',
20
- });
21
- const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
22
- const { output, formatted, effectLabel, nodeLabel, logLine } = await (0, add_effect_1.addEffect)({
23
- input: fileContents,
24
- sequenceNodePath: sequenceNodePath.nodePath,
25
- effectName,
26
- effectImportPath,
27
- effectConfig,
28
- });
29
- (0, undo_stack_1.pushToUndoStack)({
30
- filePath: absolutePath,
31
- oldContents: fileContents,
32
- newContents: null,
33
- logLevel,
34
- remotionRoot,
35
- logLine,
36
- description: {
37
- undoMessage: `↩️ Addition of ${effectLabel} to ${nodeLabel}`,
38
- redoMessage: `↪️ Addition of ${effectLabel} to ${nodeLabel}`,
39
- },
40
- entryType: 'add-effect',
41
- suppressHmrOnFileRestore: false,
42
- });
43
- (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
44
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
45
- const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
46
- remotionRoot,
47
- absolutePath,
48
- line: logLine,
49
- });
50
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Added ${(0, formatting_1.attrName)(effectLabel)} to ${nodeLabel}`);
51
- if (!formatted) {
52
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
13
+ const source_file_write_queue_1 = require("./source-file-write-queue");
14
+ const addEffectHandler = ({ input: { fileName, sequenceNodePath, effectName, effectImportPath, effectConfig, clientId, }, remotionRoot, logLevel, }) => {
15
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
16
+ try {
17
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-effect] Received request for fileName="${fileName}" effect="${effectName}"`);
18
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
19
+ remotionRoot,
20
+ fileName,
21
+ action: 'modify',
22
+ });
23
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
24
+ const { output, formatted, effectLabel, nodeLabel, logLine } = await (0, add_effect_1.addEffect)({
25
+ input: fileContents,
26
+ sequenceNodePath: sequenceNodePath.nodePath,
27
+ effectName,
28
+ effectImportPath,
29
+ effectConfig,
30
+ });
31
+ (0, undo_stack_1.pushToUndoStack)({
32
+ filePath: absolutePath,
33
+ oldContents: fileContents,
34
+ newContents: null,
35
+ logLevel,
36
+ remotionRoot,
37
+ logLine,
38
+ description: {
39
+ undoMessage: `↩️ Addition of ${effectLabel} to ${nodeLabel}`,
40
+ redoMessage: `↪️ Addition of ${effectLabel} to ${nodeLabel}`,
41
+ },
42
+ entryType: 'add-effect',
43
+ suppressHmrOnFileRestore: false,
44
+ });
45
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
46
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
47
+ const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
48
+ remotionRoot,
49
+ absolutePath,
50
+ line: logLine,
51
+ });
52
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Added ${(0, formatting_1.attrName)(effectLabel)} to ${nodeLabel}`);
53
+ if (!formatted) {
54
+ (0, log_update_1.warnAboutPrettierOnce)(logLevel);
55
+ }
56
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[add-effect] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
57
+ (0, undo_stack_1.printUndoHint)(logLevel);
58
+ return {
59
+ success: true,
60
+ };
53
61
  }
54
- renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[add-effect] Wrote ${fileRelativeToRoot}${formatted ? ' (formatted)' : ''}`);
55
- (0, undo_stack_1.printUndoHint)(logLevel);
56
- return {
57
- success: true,
58
- };
59
- }
60
- catch (err) {
61
- return {
62
- success: false,
63
- reason: err.message,
64
- stack: err.stack,
65
- };
66
- }
62
+ catch (err) {
63
+ return {
64
+ success: false,
65
+ reason: err.message,
66
+ stack: err.stack,
67
+ };
68
+ }
69
+ });
67
70
  };
68
71
  exports.addEffectHandler = addEffectHandler;
@@ -10,7 +10,7 @@ const undo_stack_1 = require("../undo-stack");
10
10
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
11
11
  const log_effect_update_1 = require("./log-updates/log-effect-update");
12
12
  const log_update_1 = require("./log-updates/log-update");
13
- const save_props_mutex_1 = require("./save-props-mutex");
13
+ const source_file_write_queue_1 = require("./source-file-write-queue");
14
14
  const groupBy = (items, getKey) => {
15
15
  var _a;
16
16
  const groups = new Map();
@@ -212,7 +212,7 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
212
212
  (0, undo_stack_1.printUndoHint)(logLevel);
213
213
  };
214
214
  exports.addKeyframes = addKeyframes;
215
- const addKeyframesHandler = ({ input: { sequenceKeyframes, effectKeyframes, clientId }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
215
+ const addKeyframesHandler = ({ input: { sequenceKeyframes, effectKeyframes, clientId }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
216
216
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-keyframes] Received request to add ${sequenceKeyframes.length + effectKeyframes.length} keyframe(s)`);
217
217
  await (0, exports.addKeyframes)({
218
218
  sequenceKeyframes,
@@ -11,8 +11,8 @@ const undo_stack_1 = require("../undo-stack");
11
11
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
12
12
  const can_update_sequence_props_1 = require("./can-update-sequence-props");
13
13
  const log_update_1 = require("./log-updates/log-update");
14
- const save_props_mutex_1 = require("./save-props-mutex");
15
- const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, value, schema, clientId }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
14
+ const source_file_write_queue_1 = require("./source-file-write-queue");
15
+ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, value, schema, clientId }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
16
16
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[add-sequence-keyframe] Received request for fileName="${fileName}" key="${key}" frame=${frame}`);
17
17
  const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
18
18
  remotionRoot,
@@ -14,6 +14,7 @@ const file_watcher_1 = require("../../file-watcher");
14
14
  const project_info_1 = require("../project-info");
15
15
  const undo_stack_1 = require("../undo-stack");
16
16
  const can_update_default_props_1 = require("./can-update-default-props");
17
+ const source_file_write_queue_1 = require("./source-file-write-queue");
17
18
  const formatNewCompositionFile = (componentName) => {
18
19
  return (0, duplicate_composition_1.formatOutput)(`import React from 'react';
19
20
 
@@ -77,110 +78,112 @@ const getCodemodUndoDescription = (codemod) => {
77
78
  entryType: 'visual-control',
78
79
  };
79
80
  };
80
- const applyCodemodHandler = async ({ input: { codemod, dryRun, symbolicatedStack }, logLevel, remotionRoot, entryPoint, }) => {
81
- var _a, _b;
82
- try {
83
- const time = Date.now();
84
- const filePath = symbolicatedStack
85
- ? (0, apply_codemod_to_file_1.resolveFilePathFromSymbolicatedStack)(remotionRoot, symbolicatedStack)
86
- : (await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint)).rootFile;
87
- if (!filePath) {
88
- throw new Error('Cannot find file for composition in project');
89
- }
90
- (0, can_update_default_props_1.checkIfTypeScriptFile)(filePath);
91
- const newCompositionComponentFilePath = codemod.type === 'new-composition'
92
- ? node_path_1.default.join(node_path_1.default.dirname(filePath), `${codemod.componentName}.tsx`)
93
- : null;
94
- if (codemod.type === 'new-composition' &&
95
- newCompositionComponentFilePath &&
96
- (0, node_fs_1.existsSync)(newCompositionComponentFilePath)) {
97
- throw new Error(`Cannot create ${node_path_1.default.relative(remotionRoot, newCompositionComponentFilePath)} because it already exists`);
98
- }
99
- const input = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
100
- const formatted = await (0, apply_codemod_to_file_1.applyCodemodToFile)({
101
- filePath,
102
- codeMod: codemod,
103
- });
104
- const diff = (0, simple_diff_1.simpleDiff)({
105
- oldLines: input.split('\n'),
106
- newLines: formatted.split('\n'),
107
- });
108
- if (!dryRun) {
109
- const { entryType, undoMessage, redoMessage } = getCodemodUndoDescription(codemod);
110
- const snapshots = [
111
- {
112
- filePath,
113
- oldContents: input,
114
- newContents: null,
115
- logLine: (_a = symbolicatedStack === null || symbolicatedStack === void 0 ? void 0 : symbolicatedStack.originalLineNumber) !== null && _a !== void 0 ? _a : 1,
116
- },
117
- ];
118
- let componentFilePath = null;
119
- let componentFileContents = null;
120
- if (codemod.type === 'new-composition') {
121
- componentFilePath = newCompositionComponentFilePath;
122
- if (componentFilePath === null) {
123
- throw new Error('Could not determine the new component file path');
124
- }
125
- componentFileContents = await formatNewCompositionFile(codemod.componentName);
126
- snapshots.push({
127
- filePath: componentFilePath,
128
- oldContents: null,
129
- newContents: componentFileContents,
130
- logLine: 1,
131
- });
132
- (0, undo_stack_1.pushTransactionToUndoStack)({
133
- snapshots,
134
- logLevel,
135
- remotionRoot,
136
- description: {
137
- undoMessage,
138
- redoMessage,
139
- },
140
- entryType,
141
- suppressHmrOnFileRestore: false,
142
- });
81
+ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, logLevel, remotionRoot, entryPoint, }) => {
82
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
83
+ var _a, _b;
84
+ try {
85
+ const time = Date.now();
86
+ const filePath = symbolicatedStack
87
+ ? (0, apply_codemod_to_file_1.resolveFilePathFromSymbolicatedStack)(remotionRoot, symbolicatedStack)
88
+ : (await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint)).rootFile;
89
+ if (!filePath) {
90
+ throw new Error('Cannot find file for composition in project');
143
91
  }
144
- else {
145
- (0, undo_stack_1.pushToUndoStack)({
146
- filePath,
147
- oldContents: input,
148
- newContents: null,
149
- logLevel,
150
- remotionRoot,
151
- logLine: (_b = symbolicatedStack === null || symbolicatedStack === void 0 ? void 0 : symbolicatedStack.originalLineNumber) !== null && _b !== void 0 ? _b : 1,
152
- description: {
153
- undoMessage,
154
- redoMessage,
155
- },
156
- entryType,
157
- suppressHmrOnFileRestore: false,
158
- });
92
+ (0, can_update_default_props_1.checkIfTypeScriptFile)(filePath);
93
+ const newCompositionComponentFilePath = codemod.type === 'new-composition'
94
+ ? node_path_1.default.join(node_path_1.default.dirname(filePath), `${codemod.componentName}.tsx`)
95
+ : null;
96
+ if (codemod.type === 'new-composition' &&
97
+ newCompositionComponentFilePath &&
98
+ (0, node_fs_1.existsSync)(newCompositionComponentFilePath)) {
99
+ throw new Error(`Cannot create ${node_path_1.default.relative(remotionRoot, newCompositionComponentFilePath)} because it already exists`);
159
100
  }
160
- (0, undo_stack_1.suppressUndoStackInvalidation)(filePath);
161
- if (componentFilePath) {
162
- (0, undo_stack_1.suppressUndoStackInvalidation)(componentFilePath);
163
- }
164
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(filePath, formatted, undefined);
165
- if (componentFilePath && componentFileContents !== null) {
166
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(componentFilePath, componentFileContents, undefined);
101
+ const input = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
102
+ const formatted = await (0, apply_codemod_to_file_1.applyCodemodToFile)({
103
+ filePath,
104
+ codeMod: codemod,
105
+ });
106
+ const diff = (0, simple_diff_1.simpleDiff)({
107
+ oldLines: input.split('\n'),
108
+ newLines: formatted.split('\n'),
109
+ });
110
+ if (!dryRun) {
111
+ const { entryType, undoMessage, redoMessage } = getCodemodUndoDescription(codemod);
112
+ const snapshots = [
113
+ {
114
+ filePath,
115
+ oldContents: input,
116
+ newContents: null,
117
+ logLine: (_a = symbolicatedStack === null || symbolicatedStack === void 0 ? void 0 : symbolicatedStack.originalLineNumber) !== null && _a !== void 0 ? _a : 1,
118
+ },
119
+ ];
120
+ let componentFilePath = null;
121
+ let componentFileContents = null;
122
+ if (codemod.type === 'new-composition') {
123
+ componentFilePath = newCompositionComponentFilePath;
124
+ if (componentFilePath === null) {
125
+ throw new Error('Could not determine the new component file path');
126
+ }
127
+ componentFileContents = await formatNewCompositionFile(codemod.componentName);
128
+ snapshots.push({
129
+ filePath: componentFilePath,
130
+ oldContents: null,
131
+ newContents: componentFileContents,
132
+ logLine: 1,
133
+ });
134
+ (0, undo_stack_1.pushTransactionToUndoStack)({
135
+ snapshots,
136
+ logLevel,
137
+ remotionRoot,
138
+ description: {
139
+ undoMessage,
140
+ redoMessage,
141
+ },
142
+ entryType,
143
+ suppressHmrOnFileRestore: false,
144
+ });
145
+ }
146
+ else {
147
+ (0, undo_stack_1.pushToUndoStack)({
148
+ filePath,
149
+ oldContents: input,
150
+ newContents: null,
151
+ logLevel,
152
+ remotionRoot,
153
+ logLine: (_b = symbolicatedStack === null || symbolicatedStack === void 0 ? void 0 : symbolicatedStack.originalLineNumber) !== null && _b !== void 0 ? _b : 1,
154
+ description: {
155
+ undoMessage,
156
+ redoMessage,
157
+ },
158
+ entryType,
159
+ suppressHmrOnFileRestore: false,
160
+ });
161
+ }
162
+ (0, undo_stack_1.suppressUndoStackInvalidation)(filePath);
163
+ if (componentFilePath) {
164
+ (0, undo_stack_1.suppressUndoStackInvalidation)(componentFilePath);
165
+ }
166
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(filePath, formatted, undefined);
167
+ if (componentFilePath && componentFileContents !== null) {
168
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(componentFilePath, componentFileContents, undefined);
169
+ }
170
+ const end = Date.now() - time;
171
+ const relativePath = node_path_1.default.relative(remotionRoot, filePath);
172
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Edited ${relativePath} in ${end}ms`));
173
+ (0, undo_stack_1.printUndoHint)(logLevel);
167
174
  }
168
- const end = Date.now() - time;
169
- const relativePath = node_path_1.default.relative(remotionRoot, filePath);
170
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Edited ${relativePath} in ${end}ms`));
171
- (0, undo_stack_1.printUndoHint)(logLevel);
175
+ return {
176
+ success: true,
177
+ diff,
178
+ };
172
179
  }
173
- return {
174
- success: true,
175
- diff,
176
- };
177
- }
178
- catch (err) {
179
- return {
180
- success: false,
181
- reason: err.message,
182
- stack: err.stack,
183
- };
184
- }
180
+ catch (err) {
181
+ return {
182
+ success: false,
183
+ reason: err.message,
184
+ stack: err.stack,
185
+ };
186
+ }
187
+ });
185
188
  };
186
189
  exports.applyCodemodHandler = applyCodemodHandler;
@@ -46,6 +46,7 @@ const live_events_1 = require("../live-events");
46
46
  const undo_stack_1 = require("../undo-stack");
47
47
  const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
48
48
  const log_update_1 = require("./log-updates/log-update");
49
+ const source_file_write_queue_1 = require("./source-file-write-queue");
49
50
  const getVisualControlChangeLine = (file, changeId) => {
50
51
  let line = 1;
51
52
  recast.types.visit(file.program, {
@@ -66,89 +67,91 @@ const getVisualControlChangeLine = (file, changeId) => {
66
67
  });
67
68
  return line;
68
69
  };
69
- const applyVisualControlHandler = async ({ input: { fileName, changes }, remotionRoot, logLevel }) => {
70
- renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[apply-visual-control] Received request for ${fileName} with ${changes.length} changes`);
71
- const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
72
- remotionRoot,
73
- fileName,
74
- action: 'apply visual control change to',
75
- });
76
- const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
77
- const ast = (0, parse_ast_1.parseAst)(fileContents);
78
- const logLine = changes.length > 0 ? getVisualControlChangeLine(ast, changes[0].id) : 1;
79
- const { newAst, changesMade } = (0, recast_mods_1.applyCodemod)({
80
- file: ast,
81
- codeMod: {
82
- type: 'apply-visual-control',
83
- changes,
84
- },
85
- });
86
- if (changesMade.length === 0) {
87
- throw new Error('No changes were made to the file');
88
- }
89
- let output = (0, parse_ast_1.serializeAst)(newAst);
90
- let formatted = false;
91
- try {
92
- const prettier = await Promise.resolve().then(() => __importStar(require('prettier')));
93
- const { format, resolveConfig, resolveConfigFile } = prettier;
94
- const configFilePath = await resolveConfigFile();
95
- if (configFilePath) {
96
- const prettierConfig = await resolveConfig(configFilePath);
97
- if (prettierConfig) {
98
- output = await format(output, {
99
- ...prettierConfig,
100
- filepath: 'test.tsx',
101
- plugins: [],
102
- endOfLine: 'auto',
103
- });
104
- formatted = true;
70
+ const applyVisualControlHandler = ({ input: { fileName, changes }, remotionRoot, logLevel }) => {
71
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
72
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[apply-visual-control] Received request for ${fileName} with ${changes.length} changes`);
73
+ const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
74
+ remotionRoot,
75
+ fileName,
76
+ action: 'apply visual control change to',
77
+ });
78
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
79
+ const ast = (0, parse_ast_1.parseAst)(fileContents);
80
+ const logLine = changes.length > 0 ? getVisualControlChangeLine(ast, changes[0].id) : 1;
81
+ const { newAst, changesMade } = (0, recast_mods_1.applyCodemod)({
82
+ file: ast,
83
+ codeMod: {
84
+ type: 'apply-visual-control',
85
+ changes,
86
+ },
87
+ });
88
+ if (changesMade.length === 0) {
89
+ throw new Error('No changes were made to the file');
90
+ }
91
+ let output = (0, parse_ast_1.serializeAst)(newAst);
92
+ let formatted = false;
93
+ try {
94
+ const prettier = await Promise.resolve().then(() => __importStar(require('prettier')));
95
+ const { format, resolveConfig, resolveConfigFile } = prettier;
96
+ const configFilePath = await resolveConfigFile();
97
+ if (configFilePath) {
98
+ const prettierConfig = await resolveConfig(configFilePath);
99
+ if (prettierConfig) {
100
+ output = await format(output, {
101
+ ...prettierConfig,
102
+ filepath: 'test.tsx',
103
+ plugins: [],
104
+ endOfLine: 'auto',
105
+ });
106
+ formatted = true;
107
+ }
105
108
  }
106
109
  }
107
- }
108
- catch (_a) {
109
- // Prettier not available, use unformatted output
110
- }
111
- (0, undo_stack_1.pushToUndoStack)({
112
- filePath: absolutePath,
113
- oldContents: fileContents,
114
- newContents: null,
115
- logLevel,
116
- remotionRoot,
117
- logLine,
118
- description: {
119
- undoMessage: '↩️ Visual control change',
120
- redoMessage: '↪️ Visual control change',
121
- },
122
- entryType: 'visual-control',
123
- suppressHmrOnFileRestore: true,
124
- });
125
- (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
126
- (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
127
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, undefined);
128
- (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
129
- listener.sendEventToClient({
130
- type: 'visual-control-values-changed',
131
- values: changes.map((change) => ({
132
- id: change.id,
133
- value: change.newValueIsUndefined
134
- ? null
135
- : JSON.parse(change.newValueSerialized),
136
- isUndefined: change.newValueIsUndefined,
137
- })),
110
+ catch (_a) {
111
+ // Prettier not available, use unformatted output
112
+ }
113
+ (0, undo_stack_1.pushToUndoStack)({
114
+ filePath: absolutePath,
115
+ oldContents: fileContents,
116
+ newContents: null,
117
+ logLevel,
118
+ remotionRoot,
119
+ logLine,
120
+ description: {
121
+ undoMessage: '↩️ Visual control change',
122
+ redoMessage: '↪️ Visual control change',
123
+ },
124
+ entryType: 'visual-control',
125
+ suppressHmrOnFileRestore: true,
138
126
  });
127
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
128
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
129
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, undefined);
130
+ (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
131
+ listener.sendEventToClient({
132
+ type: 'visual-control-values-changed',
133
+ values: changes.map((change) => ({
134
+ id: change.id,
135
+ value: change.newValueIsUndefined
136
+ ? null
137
+ : JSON.parse(change.newValueSerialized),
138
+ isUndefined: change.newValueIsUndefined,
139
+ })),
140
+ });
141
+ });
142
+ const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
143
+ remotionRoot,
144
+ absolutePath,
145
+ line: logLine,
146
+ });
147
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Applied visual control changes`);
148
+ if (!formatted) {
149
+ (0, log_update_1.warnAboutPrettierOnce)(logLevel);
150
+ }
151
+ (0, undo_stack_1.printUndoHint)(logLevel);
152
+ return {
153
+ success: true,
154
+ };
139
155
  });
140
- const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
141
- remotionRoot,
142
- absolutePath,
143
- line: logLine,
144
- });
145
- renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${locationLabel}`)} Applied visual control changes`);
146
- if (!formatted) {
147
- (0, log_update_1.warnAboutPrettierOnce)(logLevel);
148
- }
149
- (0, undo_stack_1.printUndoHint)(logLevel);
150
- return {
151
- success: true,
152
- };
153
156
  };
154
157
  exports.applyVisualControlHandler = applyVisualControlHandler;
@@ -1,4 +1,4 @@
1
- import type { Expression, File, JSXOpeningElement } from '@babel/types';
1
+ import type { Expression, File, JSXElement, JSXOpeningElement } from '@babel/types';
2
2
  import type { SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
3
3
  import type { CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, SequenceNodePath } from 'remotion';
4
4
  type StaticValueOptions = {
@@ -7,7 +7,19 @@ type StaticValueOptions = {
7
7
  export declare const isStaticValue: (node: Expression, options?: StaticValueOptions) => boolean;
8
8
  export declare const extractStaticValue: (node: Expression, options?: StaticValueOptions) => unknown;
9
9
  export declare const getComputedStatus: (node: Expression, ast: File) => CanUpdateSequencePropStatus;
10
+ export declare const findJsxElementPathAtNodePath: (ast: File, nodePath: SequenceNodePath) => import("ast-types/lib/node-path").NodePath<N, V> | null;
10
11
  export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
12
+ export declare const findJsxElementNodeAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXElement | null;
13
+ export type StaticJsxTextContent = {
14
+ kind: 'jsx-text';
15
+ value: string;
16
+ } | {
17
+ kind: 'string-expression';
18
+ value: string;
19
+ };
20
+ export declare const getStaticJsxChildrenAttribute: (jsxElement: JSXOpeningElement) => StaticJsxTextContent | null;
21
+ export declare const hasJsxChildrenAttribute: (jsxElement: JSXOpeningElement) => boolean;
22
+ export declare const getStaticJsxTextContent: (jsxElement: JSXElement) => StaticJsxTextContent | null;
11
23
  export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
12
24
  export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
13
25
  export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, componentIdentity, keys, effects, }: {