@remotion/studio-server 4.0.134 → 4.0.136

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.
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @remotion/studio-server@4.0.134 build /Users/jonathanburger/remotion/packages/studio-server
3
+ > @remotion/studio-server@4.0.135 build /Users/jonathanburger/remotion/packages/studio-server
4
4
  > tsc -d
5
5
 
@@ -0,0 +1,10 @@
1
+ import type { RecastCodemod } from '@remotion/studio-shared';
2
+ import type { Change } from './recast-mods';
3
+ export declare const formatOutput: (tsContent: string) => Promise<string>;
4
+ export declare const parseAndApplyCodemod: ({ input, codeMod, }: {
5
+ input: string;
6
+ codeMod: RecastCodemod;
7
+ }) => {
8
+ newContents: string;
9
+ changesMade: Change[];
10
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.parseAndApplyCodemod = exports.formatOutput = void 0;
27
+ const recast = __importStar(require("recast"));
28
+ const tsParser = __importStar(require("recast/parsers/babel-ts"));
29
+ const recast_mods_1 = require("./recast-mods");
30
+ const getPrettier = async () => {
31
+ try {
32
+ return await Promise.resolve().then(() => __importStar(require('prettier')));
33
+ }
34
+ catch (err) {
35
+ throw new Error('Prettier cannot be found in the current project.');
36
+ }
37
+ };
38
+ const formatOutput = async (tsContent) => {
39
+ const prettier = await getPrettier();
40
+ const { format, resolveConfig, resolveConfigFile } = prettier;
41
+ const configFilePath = await resolveConfigFile();
42
+ if (!configFilePath) {
43
+ throw new Error('The Prettier config file was not found');
44
+ }
45
+ const prettierConfig = await resolveConfig(configFilePath);
46
+ if (!prettierConfig) {
47
+ throw new Error(`The Prettier config at ${configFilePath} could not be read`);
48
+ }
49
+ const newContents = await format(tsContent, {
50
+ ...prettierConfig,
51
+ filepath: 'test.tsx',
52
+ });
53
+ return newContents;
54
+ };
55
+ exports.formatOutput = formatOutput;
56
+ const parseAndApplyCodemod = ({ input, codeMod, }) => {
57
+ const ast = recast.parse(input, {
58
+ parser: tsParser,
59
+ });
60
+ const { newAst, changesMade } = (0, recast_mods_1.applyCodemod)({
61
+ file: ast,
62
+ codeMod,
63
+ });
64
+ if (changesMade.length === 0) {
65
+ throw new Error('Unable to calculate the changes needed for this file. Edit the root file manually.');
66
+ }
67
+ const output = recast.print(newAst, {
68
+ parser: tsParser,
69
+ }).code;
70
+ return { changesMade, newContents: output };
71
+ };
72
+ exports.parseAndApplyCodemod = parseAndApplyCodemod;
@@ -0,0 +1,12 @@
1
+ import type { File } from '@babel/types';
2
+ import type { RecastCodemod } from '@remotion/studio-shared';
3
+ export type Change = {
4
+ description: string;
5
+ };
6
+ export declare const applyCodemod: ({ file, codeMod, }: {
7
+ file: File;
8
+ codeMod: RecastCodemod;
9
+ }) => {
10
+ newAst: File;
11
+ changesMade: Change[];
12
+ };
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyCodemod = void 0;
4
+ const applyCodemod = ({ file, codeMod, }) => {
5
+ const changesMade = [];
6
+ const body = file.program.body.map((node) => {
7
+ return mapAll(node, codeMod, changesMade);
8
+ });
9
+ return {
10
+ newAst: {
11
+ ...file,
12
+ program: {
13
+ ...file.program,
14
+ body,
15
+ },
16
+ },
17
+ changesMade,
18
+ };
19
+ };
20
+ exports.applyCodemod = applyCodemod;
21
+ const mapAll = (node, transformation, changesMade) => {
22
+ if (isRecognizedType(node)) {
23
+ return mapRecognizedType(node, transformation, changesMade);
24
+ }
25
+ return node;
26
+ };
27
+ const isRecognizedType = (t) => {
28
+ return (t.type === 'ArrowFunctionExpression' ||
29
+ t.type === 'FunctionExpression' ||
30
+ t.type === 'JSXFragment' ||
31
+ t.type === 'JSXElement' ||
32
+ t.type === 'BlockStatement' ||
33
+ t.type === 'ReturnStatement' ||
34
+ t.type === 'VariableDeclaration' ||
35
+ t.type === 'FunctionDeclaration' ||
36
+ t.type === 'ExportNamedDeclaration' ||
37
+ t.type === 'ExportDefaultDeclaration');
38
+ };
39
+ const mapVariableDeclarator = (variableDeclarator, transformation, changesMade) => {
40
+ return {
41
+ ...variableDeclarator,
42
+ init: variableDeclarator.init
43
+ ? mapAll(variableDeclarator.init, transformation, changesMade)
44
+ : variableDeclarator.init,
45
+ };
46
+ };
47
+ const mapBlockStatement = (blockStatement, transformation, changesMade) => {
48
+ return {
49
+ ...blockStatement,
50
+ body: blockStatement.body.map((a) => {
51
+ return mapAll(a, transformation, changesMade);
52
+ }),
53
+ };
54
+ };
55
+ const mapReturnStatement = (statement, transformation, changesMade) => {
56
+ if (!statement.argument) {
57
+ return statement;
58
+ }
59
+ return {
60
+ ...statement,
61
+ argument: mapAll(statement.argument, transformation, changesMade),
62
+ };
63
+ };
64
+ const mapJsxElementOrFragment = (jsxFragment, transformation, changesMade) => {
65
+ return {
66
+ ...jsxFragment,
67
+ children: jsxFragment.children
68
+ .map((c) => {
69
+ if (c.type !== 'JSXElement') {
70
+ return c;
71
+ }
72
+ return mapJsxChild(c, transformation, changesMade);
73
+ })
74
+ .flat(1),
75
+ };
76
+ };
77
+ const mapJsxChild = (c, transformation, changesMade) => {
78
+ const compId = getCompositionIdFromJSXElement(c);
79
+ if (transformation === null) {
80
+ return [c];
81
+ }
82
+ if (transformation.type === 'duplicate-composition' &&
83
+ compId === transformation.idToDuplicate) {
84
+ return [
85
+ c,
86
+ changeComposition({
87
+ jsxElement: c,
88
+ newCompositionId: transformation.newId,
89
+ newCompositionFps: transformation.newFps,
90
+ newCompositionDurationInFrames: transformation.newDurationInFrames,
91
+ newCompositionHeight: transformation.newHeight,
92
+ newCompositionWidth: transformation.newWidth,
93
+ newTagToUse: transformation.tag,
94
+ changesMade,
95
+ }),
96
+ ];
97
+ }
98
+ if (transformation.type === 'rename-composition' &&
99
+ compId === transformation.idToRename) {
100
+ return [
101
+ changeComposition({
102
+ jsxElement: c,
103
+ newCompositionId: transformation.newId,
104
+ newCompositionFps: null,
105
+ newCompositionDurationInFrames: null,
106
+ newCompositionHeight: null,
107
+ newCompositionWidth: null,
108
+ changesMade,
109
+ newTagToUse: null,
110
+ }),
111
+ ];
112
+ }
113
+ if (transformation.type === 'delete-composition' &&
114
+ compId === transformation.idToDelete) {
115
+ changesMade.push({
116
+ description: 'Deleted composition',
117
+ });
118
+ return [];
119
+ }
120
+ return [mapAll(c, transformation, changesMade)];
121
+ };
122
+ const mapRecognizedType = (expression, transformation, changesMade) => {
123
+ if (expression.type === 'JSXFragment' || expression.type === 'JSXElement') {
124
+ return mapJsxElementOrFragment(expression, transformation, changesMade);
125
+ }
126
+ if (expression.type === 'ArrowFunctionExpression' ||
127
+ expression.type === 'FunctionExpression') {
128
+ return {
129
+ ...expression,
130
+ body: mapAll(expression.body, transformation, changesMade),
131
+ };
132
+ }
133
+ if (expression.type === 'VariableDeclaration') {
134
+ const declarations = expression.declarations.map((d) => {
135
+ return mapVariableDeclarator(d, transformation, changesMade);
136
+ });
137
+ return { ...expression, declarations };
138
+ }
139
+ if (expression.type === 'FunctionDeclaration') {
140
+ return {
141
+ ...expression,
142
+ body: mapBlockStatement(expression.body, transformation, changesMade),
143
+ };
144
+ }
145
+ if (expression.type === 'ExportNamedDeclaration' ||
146
+ expression.type === 'ExportDefaultDeclaration') {
147
+ if (!expression.declaration) {
148
+ return expression;
149
+ }
150
+ return {
151
+ ...expression,
152
+ declaration: mapAll(expression.declaration, transformation, changesMade),
153
+ };
154
+ }
155
+ if (expression.type === 'ReturnStatement') {
156
+ return mapReturnStatement(expression, transformation, changesMade);
157
+ }
158
+ if (expression.type === 'BlockStatement') {
159
+ return mapBlockStatement(expression, transformation, changesMade);
160
+ }
161
+ return expression;
162
+ };
163
+ const getCompositionIdFromJSXElement = (jsxElement) => {
164
+ if (jsxElement.type !== 'JSXElement') {
165
+ return null;
166
+ }
167
+ const { openingElement } = jsxElement;
168
+ const { name } = openingElement;
169
+ if (name.type !== 'JSXIdentifier') {
170
+ return null;
171
+ }
172
+ if (name.name !== 'Composition' && name.name !== 'Still') {
173
+ return null;
174
+ }
175
+ const id = openingElement.attributes
176
+ .map((attribute) => {
177
+ if (attribute.type === 'JSXSpreadAttribute') {
178
+ return null;
179
+ }
180
+ if (attribute.name.type === 'JSXNamespacedName') {
181
+ return null;
182
+ }
183
+ if (attribute.name.name !== 'id') {
184
+ return null;
185
+ }
186
+ if (!attribute.value) {
187
+ return null;
188
+ }
189
+ if (attribute.value.type === 'StringLiteral') {
190
+ return attribute.value.value;
191
+ }
192
+ if (attribute.value.type === 'JSXExpressionContainer' &&
193
+ attribute.value.expression.type === 'StringLiteral') {
194
+ return attribute.value.expression.value;
195
+ }
196
+ return null;
197
+ })
198
+ .filter(Boolean);
199
+ return id[0];
200
+ };
201
+ const changeComposition = ({ jsxElement, newCompositionId, newCompositionFps, newCompositionDurationInFrames, newCompositionHeight, newCompositionWidth, changesMade, newTagToUse, }) => {
202
+ const { openingElement } = jsxElement;
203
+ const { name } = openingElement;
204
+ if (name.type !== 'JSXIdentifier') {
205
+ return jsxElement;
206
+ }
207
+ if (name.name !== 'Composition' && name.name !== 'Still') {
208
+ return jsxElement;
209
+ }
210
+ const attributes = openingElement.attributes
211
+ .map((attribute) => {
212
+ if (attribute.type === 'JSXSpreadAttribute') {
213
+ return attribute;
214
+ }
215
+ if (attribute.name.type === 'JSXNamespacedName') {
216
+ return attribute;
217
+ }
218
+ if (attribute.name.name === 'fps' && newTagToUse === 'Still') {
219
+ changesMade.push({ description: 'Removed fps attribute' });
220
+ return null;
221
+ }
222
+ if (attribute.name.name === 'durationInFrames' &&
223
+ newTagToUse === 'Still') {
224
+ changesMade.push({ description: 'Removed durationInFrames' });
225
+ return null;
226
+ }
227
+ // id="one"
228
+ if (attribute.name.name === 'id' &&
229
+ attribute.value &&
230
+ attribute.value.type === 'StringLiteral') {
231
+ changesMade.push({
232
+ description: 'Replaced composition id',
233
+ });
234
+ return {
235
+ ...attribute,
236
+ value: { ...attribute.value, value: newCompositionId },
237
+ };
238
+ }
239
+ // id={"one"}
240
+ if (attribute.name.name === 'id' &&
241
+ attribute.value &&
242
+ attribute.value.type === 'JSXExpressionContainer' &&
243
+ attribute.value.expression.type === 'StringLiteral') {
244
+ changesMade.push({
245
+ description: 'Replaced composition id',
246
+ });
247
+ return {
248
+ ...attribute,
249
+ value: {
250
+ ...attribute.value,
251
+ expression: {
252
+ ...attribute.value.expression,
253
+ value: newCompositionId,
254
+ },
255
+ },
256
+ };
257
+ }
258
+ if (attribute.name.name === 'fps' &&
259
+ attribute.value &&
260
+ attribute.value.type === 'JSXExpressionContainer' &&
261
+ attribute.value.expression.type === 'NumericLiteral' &&
262
+ newCompositionFps !== null) {
263
+ changesMade.push({
264
+ description: 'Replaced FPS',
265
+ });
266
+ return {
267
+ ...attribute,
268
+ value: {
269
+ ...attribute.value,
270
+ expression: {
271
+ ...attribute.value.expression,
272
+ value: newCompositionFps,
273
+ },
274
+ },
275
+ };
276
+ }
277
+ if (attribute.name.name === 'durationInFrames' &&
278
+ attribute.value &&
279
+ attribute.value.type === 'JSXExpressionContainer' &&
280
+ attribute.value.expression.type === 'NumericLiteral' &&
281
+ newCompositionDurationInFrames !== null) {
282
+ changesMade.push({
283
+ description: 'Replaced durationInFrames',
284
+ });
285
+ return {
286
+ ...attribute,
287
+ value: {
288
+ ...attribute.value,
289
+ expression: {
290
+ ...attribute.value.expression,
291
+ value: newCompositionDurationInFrames,
292
+ },
293
+ },
294
+ };
295
+ }
296
+ if (attribute.name.name === 'width' &&
297
+ attribute.value &&
298
+ attribute.value.type === 'JSXExpressionContainer' &&
299
+ attribute.value.expression.type === 'NumericLiteral' &&
300
+ newCompositionWidth !== null) {
301
+ changesMade.push({
302
+ description: 'Replaced width',
303
+ });
304
+ return {
305
+ ...attribute,
306
+ value: {
307
+ ...attribute.value,
308
+ expression: {
309
+ ...attribute.value.expression,
310
+ value: newCompositionWidth,
311
+ },
312
+ },
313
+ };
314
+ }
315
+ if (attribute.name.name === 'height' &&
316
+ attribute.value &&
317
+ attribute.value.type === 'JSXExpressionContainer' &&
318
+ attribute.value.expression.type === 'NumericLiteral' &&
319
+ newCompositionHeight !== null) {
320
+ changesMade.push({
321
+ description: 'Replaced height',
322
+ });
323
+ return {
324
+ ...attribute,
325
+ value: {
326
+ ...attribute.value,
327
+ expression: {
328
+ ...attribute.value.expression,
329
+ value: newCompositionHeight,
330
+ },
331
+ },
332
+ };
333
+ }
334
+ return attribute;
335
+ })
336
+ .filter(Boolean);
337
+ const newName = newTagToUse !== null && newTagToUse !== void 0 ? newTagToUse : name.name;
338
+ if (newName !== name.name) {
339
+ changesMade.push({
340
+ description: `Changed tag`,
341
+ });
342
+ }
343
+ return {
344
+ ...jsxElement,
345
+ openingElement: {
346
+ ...jsxElement.openingElement,
347
+ name: {
348
+ ...name,
349
+ name: newName,
350
+ },
351
+ attributes,
352
+ },
353
+ };
354
+ };
@@ -0,0 +1,5 @@
1
+ import type { SimpleDiff } from '@remotion/studio-shared';
2
+ export declare const simpleDiff: ({ oldLines, newLines, }: {
3
+ oldLines: string[];
4
+ newLines: string[];
5
+ }) => SimpleDiff;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.simpleDiff = void 0;
4
+ const findDeletions = ({ oldLines, newLines, }) => {
5
+ const linesChecked = [];
6
+ let totalDeletions = 0;
7
+ for (const line of oldLines) {
8
+ if (linesChecked.includes(line)) {
9
+ continue;
10
+ }
11
+ const timesInNewLines = newLines.filter((l) => l === line).length;
12
+ const timesInOldLines = oldLines.filter((l) => l === line).length;
13
+ const deletions = Math.max(0, timesInOldLines - timesInNewLines);
14
+ totalDeletions += deletions;
15
+ linesChecked.push(line);
16
+ }
17
+ return totalDeletions;
18
+ };
19
+ const findAdditions = ({ oldLines, newLines, }) => {
20
+ const linesChecked = [];
21
+ let totalAdditions = 0;
22
+ for (const line of newLines) {
23
+ if (linesChecked.includes(line)) {
24
+ continue;
25
+ }
26
+ const timesInNewLines = newLines.filter((l) => l === line).length;
27
+ const timesInOldLines = oldLines.filter((l) => l === line).length;
28
+ const additions = Math.max(0, timesInNewLines - timesInOldLines);
29
+ totalAdditions += additions;
30
+ linesChecked.push(line);
31
+ }
32
+ return totalAdditions;
33
+ };
34
+ const simpleDiff = ({ oldLines, newLines, }) => {
35
+ const deletions = findDeletions({ oldLines, newLines });
36
+ const additions = findAdditions({ oldLines, newLines });
37
+ return { deletions, additions };
38
+ };
39
+ exports.simpleDiff = simpleDiff;
@@ -124,7 +124,7 @@ const updateDefaultProps = async ({ input, compositionId, newDefaultProps, enumP
124
124
  if (!prettierConfig) {
125
125
  throw new Error(`The Prettier config at ${configFilePath} could not be read`);
126
126
  }
127
- const prettified = format(newFile, {
127
+ const prettified = await format(newFile, {
128
128
  ...prettierConfig,
129
129
  rangeStart: startPos,
130
130
  rangeEnd: endPos,
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const StudioServerInternals: {
5
5
  startStudio: ({ browserArgs, browserFlag, configValueShouldOpenBrowser, fullEntryPath, logLevel, getCurrentInputProps, getEnvVariables, desiredPort, maxTimelineTracks, remotionRoot, keyboardShortcutsEnabled, relativePublicDir, webpackOverride, poll, getRenderDefaults, getRenderQueue, numberOfAudioTags, queueMethods, parsedCliOpen, previewEntry, gitSource, bufferStateDelayInMilliseconds, binariesDirectory, forceIPv4, }: {
6
6
  browserArgs: string;
7
7
  browserFlag: string;
8
- logLevel: "error" | "verbose" | "info" | "warn";
8
+ logLevel: "verbose" | "info" | "warn" | "error";
9
9
  configValueShouldOpenBrowser: boolean;
10
10
  fullEntryPath: string;
11
11
  getCurrentInputProps: () => object;
@@ -59,4 +59,11 @@ export declare const StudioServerInternals: {
59
59
  binary?: boolean | undefined;
60
60
  signed: boolean;
61
61
  }) | undefined) => string;
62
+ parseAndApplyCodemod: ({ input, codeMod, }: {
63
+ input: string;
64
+ codeMod: import("@remotion/studio-shared").RecastCodemod;
65
+ }) => {
66
+ newContents: string;
67
+ changesMade: import("./codemods/recast-mods").Change[];
68
+ };
62
69
  };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ const studio_shared_1 = require("@remotion/studio-shared");
5
5
  var studio_shared_2 = require("@remotion/studio-shared");
6
6
  Object.defineProperty(exports, "getDefaultOutLocation", { enumerable: true, get: function () { return studio_shared_2.getDefaultOutLocation; } });
7
7
  const ansi_diff_1 = require("./ansi-diff");
8
+ const duplicate_composition_1 = require("./codemods/duplicate-composition");
8
9
  const file_watcher_1 = require("./file-watcher");
9
10
  const get_latest_remotion_version_1 = require("./get-latest-remotion-version");
10
11
  const max_timeline_tracks_1 = require("./max-timeline-tracks");
@@ -24,4 +25,5 @@ exports.StudioServerInternals = {
24
25
  installFileWatcher: file_watcher_1.installFileWatcher,
25
26
  AnsiDiff: ansi_diff_1.AnsiDiff,
26
27
  formatBytes: studio_shared_1.formatBytes,
28
+ parseAndApplyCodemod: duplicate_composition_1.parseAndApplyCodemod,
27
29
  };
@@ -2,10 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.allApiRoutes = void 0;
4
4
  const add_render_1 = require("./routes/add-render");
5
+ const apply_codemod_1 = require("./routes/apply-codemod");
5
6
  const can_update_default_props_1 = require("./routes/can-update-default-props");
6
7
  const cancel_render_1 = require("./routes/cancel-render");
7
8
  const copy_still_to_clipboard_handler_1 = require("./routes/copy-still-to-clipboard-handler");
8
9
  const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
10
+ const project_info_1 = require("./routes/project-info");
9
11
  const remove_render_1 = require("./routes/remove-render");
10
12
  const subscribe_to_file_existence_1 = require("./routes/subscribe-to-file-existence");
11
13
  const unsubscribe_from_file_existence_1 = require("./routes/unsubscribe-from-file-existence");
@@ -20,6 +22,8 @@ exports.allApiRoutes = {
20
22
  '/api/open-in-file-explorer': open_in_file_explorer_1.handleOpenInFileExplorer,
21
23
  '/api/copy-still-to-clipboard': copy_still_to_clipboard_handler_1.handleCopyStillToClipboard,
22
24
  '/api/update-default-props': update_default_props_1.updateDefaultPropsHandler,
25
+ '/api/apply-codemod': apply_codemod_1.applyCodemodHandler,
23
26
  '/api/can-update-default-props': can_update_default_props_1.canUpdateDefaultPropsHandler,
24
27
  '/api/update-available': update_available_1.handleUpdate,
28
+ '/api/project-info': project_info_1.projectInfoHandler,
25
29
  };
@@ -11,5 +11,5 @@ type Range = {
11
11
  type Ranges = Range[] & {
12
12
  type?: string;
13
13
  };
14
- export declare function parseRange(size: number, str: string | string[]): -1 | Ranges | -2;
14
+ export declare function parseRange(size: number, str: string | string[]): -2 | -1 | Ranges;
15
15
  export {};
@@ -21,12 +21,10 @@ const getProjectInfo = (remotionRoot) => {
21
21
  ].map((p) => {
22
22
  return node_path_1.default.join(remotionRoot, p);
23
23
  });
24
- const videoFile = (_a = pathsToLookFor.find((p) => (0, node_fs_1.existsSync)(p))) !== null && _a !== void 0 ? _a : null;
24
+ const rootFile = (_a = pathsToLookFor.find((p) => (0, node_fs_1.existsSync)(p))) !== null && _a !== void 0 ? _a : null;
25
25
  return Promise.resolve({
26
- videoFile,
27
- relativeVideoFile: videoFile
28
- ? node_path_1.default.relative(remotionRoot, videoFile)
29
- : null,
26
+ rootFile,
27
+ relativeRootFile: rootFile ? node_path_1.default.relative(remotionRoot, rootFile) : null,
30
28
  });
31
29
  };
32
30
  exports.getProjectInfo = getProjectInfo;
@@ -0,0 +1,3 @@
1
+ import type { ApplyCodemodRequest, ApplyCodemodResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const applyCodemodHandler: ApiHandler<ApplyCodemodRequest, ApplyCodemodResponse>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyCodemodHandler = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
5
+ const node_fs_1 = require("node:fs");
6
+ const duplicate_composition_1 = require("../../codemods/duplicate-composition");
7
+ const simple_diff_1 = require("../../codemods/simple-diff");
8
+ const project_info_1 = require("../project-info");
9
+ const can_update_default_props_1 = require("./can-update-default-props");
10
+ const applyCodemodHandler = async ({ input: { codemod, dryRun }, logLevel, remotionRoot }) => {
11
+ try {
12
+ const time = Date.now();
13
+ const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot);
14
+ if (!projectInfo.rootFile) {
15
+ throw new Error('Cannot find root file in project');
16
+ }
17
+ (0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
18
+ const input = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
19
+ const { newContents } = (0, duplicate_composition_1.parseAndApplyCodemod)({
20
+ codeMod: codemod,
21
+ input,
22
+ });
23
+ const formatted = await (0, duplicate_composition_1.formatOutput)(newContents);
24
+ const diff = (0, simple_diff_1.simpleDiff)({
25
+ oldLines: input.split('\n'),
26
+ newLines: formatted.split('\n'),
27
+ });
28
+ if (!dryRun) {
29
+ (0, node_fs_1.writeFileSync)(projectInfo.rootFile, formatted);
30
+ const end = Date.now() - time;
31
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Edited root file in ${end}ms`));
32
+ }
33
+ return {
34
+ success: true,
35
+ diff,
36
+ };
37
+ }
38
+ catch (err) {
39
+ return {
40
+ success: false,
41
+ reason: err.message,
42
+ stack: err.stack,
43
+ };
44
+ }
45
+ };
46
+ exports.applyCodemodHandler = applyCodemodHandler;
@@ -9,20 +9,20 @@ const checkIfTypeScriptFile = (file) => {
9
9
  !file.endsWith('.ts') &&
10
10
  !file.endsWith('.mtsx') &&
11
11
  !file.endsWith('.mts')) {
12
- throw new Error('Cannot update default props for non-TypeScript files');
12
+ throw new Error('Cannot update Root file if not using TypeScript');
13
13
  }
14
14
  };
15
15
  exports.checkIfTypeScriptFile = checkIfTypeScriptFile;
16
16
  const canUpdateDefaultPropsHandler = async ({ input: { compositionId }, remotionRoot }) => {
17
17
  try {
18
18
  const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot);
19
- if (!projectInfo.videoFile) {
19
+ if (!projectInfo.rootFile) {
20
20
  throw new Error('Cannot find root file in project');
21
21
  }
22
- (0, exports.checkIfTypeScriptFile)(projectInfo.videoFile);
22
+ (0, exports.checkIfTypeScriptFile)(projectInfo.rootFile);
23
23
  await (0, update_default_props_1.updateDefaultProps)({
24
24
  compositionId,
25
- input: (0, node_fs_1.readFileSync)(projectInfo.videoFile, 'utf-8'),
25
+ input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
26
26
  newDefaultProps: {},
27
27
  enumPaths: [],
28
28
  });