@remotion/studio-server 4.0.464 → 4.0.466

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.
@@ -0,0 +1,691 @@
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.resolveCompositionComponent = void 0;
40
+ const node_fs_1 = __importDefault(require("node:fs"));
41
+ const node_path_1 = __importDefault(require("node:path"));
42
+ const recast = __importStar(require("recast"));
43
+ const parse_ast_1 = require("../codemods/parse-ast");
44
+ const allowedFileExtensions = new Set(['.tsx', '.ts', '.jsx', '.js']);
45
+ const extensionsToProbe = ['.tsx', '.ts', '.jsx', '.js'];
46
+ const isInRemotionRoot = ({ remotionRoot, fileName, }) => {
47
+ const relativePath = node_path_1.default.relative(remotionRoot, fileName);
48
+ return !relativePath.startsWith('..') && !node_path_1.default.isAbsolute(relativePath);
49
+ };
50
+ const readSourceFile = ({ remotionRoot, fileName, }) => {
51
+ const resolved = node_path_1.default.resolve(remotionRoot, fileName);
52
+ if (!isInRemotionRoot({ remotionRoot, fileName: resolved })) {
53
+ throw new Error(`Not allowed to open ${fileName}`);
54
+ }
55
+ if (!allowedFileExtensions.has(node_path_1.default.extname(resolved))) {
56
+ throw new Error(`Not allowed to open ${fileName}`);
57
+ }
58
+ return node_fs_1.default.promises.readFile(resolved, 'utf-8');
59
+ };
60
+ const getAttributeName = (attribute) => {
61
+ if (attribute.name.type !== 'JSXIdentifier') {
62
+ return null;
63
+ }
64
+ return attribute.name.name;
65
+ };
66
+ const findAttribute = (element, name) => {
67
+ return element.openingElement.attributes.find((attribute) => {
68
+ if (attribute.type !== 'JSXAttribute') {
69
+ return false;
70
+ }
71
+ return getAttributeName(attribute) === name;
72
+ });
73
+ };
74
+ const getStringAttributeValue = (element, name) => {
75
+ const attribute = findAttribute(element, name);
76
+ if (!(attribute === null || attribute === void 0 ? void 0 : attribute.value)) {
77
+ return null;
78
+ }
79
+ if (attribute.value.type === 'StringLiteral') {
80
+ return attribute.value.value;
81
+ }
82
+ if (attribute.value.type === 'JSXExpressionContainer' &&
83
+ attribute.value.expression.type === 'StringLiteral') {
84
+ return attribute.value.expression.value;
85
+ }
86
+ return null;
87
+ };
88
+ const findCompositionElement = ({ ast, compositionId, }) => {
89
+ let found = null;
90
+ recast.types.visit(ast, {
91
+ visitJSXElement(astPath) {
92
+ if (found) {
93
+ return false;
94
+ }
95
+ const node = astPath.node;
96
+ const openingName = node.openingElement.name;
97
+ if (openingName.type === 'JSXIdentifier' &&
98
+ (openingName.name === 'Composition' || openingName.name === 'Still') &&
99
+ getStringAttributeValue(node, 'id') === compositionId) {
100
+ found = node;
101
+ return false;
102
+ }
103
+ this.traverse(astPath);
104
+ return undefined;
105
+ },
106
+ });
107
+ return found;
108
+ };
109
+ const getComponentIdentifier = (element) => {
110
+ const attribute = findAttribute(element, 'component');
111
+ if (!(attribute === null || attribute === void 0 ? void 0 : attribute.value) ||
112
+ attribute.value.type !== 'JSXExpressionContainer' ||
113
+ attribute.value.expression.type !== 'Identifier') {
114
+ return null;
115
+ }
116
+ return attribute.value.expression.name;
117
+ };
118
+ const isRecord = (value) => {
119
+ return typeof value === 'object' && value !== null;
120
+ };
121
+ const findDynamicImportPath = (value) => {
122
+ if (!isRecord(value)) {
123
+ return null;
124
+ }
125
+ if (value.type === 'CallExpression' &&
126
+ isRecord(value.callee) &&
127
+ value.callee.type === 'Import' &&
128
+ Array.isArray(value.arguments) &&
129
+ isRecord(value.arguments[0]) &&
130
+ value.arguments[0].type === 'StringLiteral' &&
131
+ typeof value.arguments[0].value === 'string') {
132
+ return value.arguments[0].value;
133
+ }
134
+ for (const [key, child] of Object.entries(value)) {
135
+ if (key === 'loc' ||
136
+ key === 'start' ||
137
+ key === 'end' ||
138
+ key === 'comments' ||
139
+ key === 'leadingComments' ||
140
+ key === 'trailingComments' ||
141
+ key === 'innerComments' ||
142
+ key === 'extra' ||
143
+ key === 'original') {
144
+ continue;
145
+ }
146
+ if (Array.isArray(child)) {
147
+ for (const item of child) {
148
+ const nestedResult = findDynamicImportPath(item);
149
+ if (nestedResult) {
150
+ return nestedResult;
151
+ }
152
+ }
153
+ continue;
154
+ }
155
+ const childResult = findDynamicImportPath(child);
156
+ if (childResult) {
157
+ return childResult;
158
+ }
159
+ }
160
+ return null;
161
+ };
162
+ const getLazyImportPath = (element) => {
163
+ const attribute = findAttribute(element, 'lazyComponent');
164
+ if (!(attribute === null || attribute === void 0 ? void 0 : attribute.value) || attribute.value.type !== 'JSXExpressionContainer') {
165
+ return null;
166
+ }
167
+ return findDynamicImportPath(attribute.value.expression);
168
+ };
169
+ const findImportTarget = ({ ast, componentName, }) => {
170
+ let found = null;
171
+ recast.types.visit(ast, {
172
+ visitImportDeclaration(astPath) {
173
+ var _a;
174
+ if (found) {
175
+ return false;
176
+ }
177
+ const node = astPath.node;
178
+ if (typeof node.source.value !== 'string') {
179
+ return false;
180
+ }
181
+ const matchingSpecifier = (_a = node.specifiers) === null || _a === void 0 ? void 0 : _a.find((specifier) => {
182
+ var _a;
183
+ return ((_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) === componentName;
184
+ });
185
+ if (!matchingSpecifier) {
186
+ return false;
187
+ }
188
+ if (matchingSpecifier.type === 'ImportDefaultSpecifier') {
189
+ found = {
190
+ importPath: node.source.value,
191
+ exportName: 'default',
192
+ };
193
+ return false;
194
+ }
195
+ if (matchingSpecifier.type === 'ImportSpecifier' &&
196
+ matchingSpecifier.imported.type === 'Identifier') {
197
+ found = {
198
+ importPath: node.source.value,
199
+ exportName: matchingSpecifier.imported.name,
200
+ };
201
+ return false;
202
+ }
203
+ if (matchingSpecifier.type === 'ImportSpecifier' &&
204
+ matchingSpecifier.imported.type === 'StringLiteral') {
205
+ found = {
206
+ importPath: node.source.value,
207
+ exportName: matchingSpecifier.imported.value,
208
+ };
209
+ return false;
210
+ }
211
+ return false;
212
+ },
213
+ });
214
+ return found;
215
+ };
216
+ const getExportedName = (exported) => {
217
+ if (!exported) {
218
+ return null;
219
+ }
220
+ if (!isRecord(exported)) {
221
+ return null;
222
+ }
223
+ if (exported.type === 'Identifier' && typeof exported.name === 'string') {
224
+ return exported.name;
225
+ }
226
+ if (exported.type === 'StringLiteral' && typeof exported.value === 'string') {
227
+ return exported.value;
228
+ }
229
+ return null;
230
+ };
231
+ const getSpecifierLocalName = (specifier) => {
232
+ if (specifier.local.type === 'Identifier') {
233
+ return specifier.local.name;
234
+ }
235
+ return null;
236
+ };
237
+ const findReExportTargets = ({ ast, exportName, }) => {
238
+ const targets = [];
239
+ recast.types.visit(ast, {
240
+ visitExportNamedDeclaration(astPath) {
241
+ var _a;
242
+ const node = astPath.node;
243
+ if (typeof ((_a = node.source) === null || _a === void 0 ? void 0 : _a.value) !== 'string') {
244
+ return false;
245
+ }
246
+ for (const specifier of node.specifiers) {
247
+ if (specifier.type !== 'ExportSpecifier') {
248
+ continue;
249
+ }
250
+ const exportedName = getExportedName(specifier.exported);
251
+ if (exportedName !== exportName) {
252
+ continue;
253
+ }
254
+ const localName = getSpecifierLocalName(specifier);
255
+ if (!localName) {
256
+ continue;
257
+ }
258
+ targets.push({
259
+ importPath: node.source.value,
260
+ exportName: localName === 'default' ? 'default' : localName,
261
+ });
262
+ }
263
+ return false;
264
+ },
265
+ visitExportAllDeclaration(astPath) {
266
+ const node = astPath.node;
267
+ if (typeof node.source.value !== 'string') {
268
+ return false;
269
+ }
270
+ targets.push({
271
+ importPath: node.source.value,
272
+ exportName,
273
+ });
274
+ return false;
275
+ },
276
+ });
277
+ return targets;
278
+ };
279
+ const resolveImportPath = ({ importPath, fromFile, }) => {
280
+ if (!importPath.startsWith('.')) {
281
+ throw new Error(`Cannot resolve non-relative import ${importPath}`);
282
+ }
283
+ const basePath = node_path_1.default.resolve(node_path_1.default.dirname(fromFile), importPath);
284
+ const candidates = node_path_1.default.extname(basePath)
285
+ ? [basePath]
286
+ : [
287
+ ...extensionsToProbe.map((extension) => `${basePath}${extension}`),
288
+ ...extensionsToProbe.map((extension) => node_path_1.default.join(basePath, `index${extension}`)),
289
+ ];
290
+ const existingFile = candidates.find((candidate) => {
291
+ return node_fs_1.default.existsSync(candidate) && node_fs_1.default.statSync(candidate).isFile();
292
+ });
293
+ if (!existingFile) {
294
+ throw new Error(`Could not find imported component file ${importPath}`);
295
+ }
296
+ return existingFile;
297
+ };
298
+ const locationFromNode = (node) => {
299
+ if (!node.loc) {
300
+ return null;
301
+ }
302
+ return {
303
+ line: node.loc.start.line,
304
+ column: node.loc.start.column,
305
+ };
306
+ };
307
+ const findLocalSymbolLocation = ({ ast, name, }) => {
308
+ let location = null;
309
+ recast.types.visit(ast, {
310
+ visitVariableDeclarator(astPath) {
311
+ if (location) {
312
+ return false;
313
+ }
314
+ const { node } = astPath;
315
+ if (node.id.type === 'Identifier' && node.id.name === name) {
316
+ location = locationFromNode(node);
317
+ return false;
318
+ }
319
+ this.traverse(astPath);
320
+ return undefined;
321
+ },
322
+ visitFunctionDeclaration(astPath) {
323
+ var _a;
324
+ if (location) {
325
+ return false;
326
+ }
327
+ const { node } = astPath;
328
+ if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
329
+ location = locationFromNode(node);
330
+ return false;
331
+ }
332
+ this.traverse(astPath);
333
+ return undefined;
334
+ },
335
+ visitClassDeclaration(astPath) {
336
+ var _a;
337
+ if (location) {
338
+ return false;
339
+ }
340
+ const { node } = astPath;
341
+ if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
342
+ location = locationFromNode(node);
343
+ return false;
344
+ }
345
+ this.traverse(astPath);
346
+ return undefined;
347
+ },
348
+ });
349
+ return location;
350
+ };
351
+ const findDefaultExportLocation = (ast) => {
352
+ let location = null;
353
+ let exportedIdentifier = null;
354
+ recast.types.visit(ast, {
355
+ visitExportDefaultDeclaration(astPath) {
356
+ var _a;
357
+ if (location || exportedIdentifier) {
358
+ return false;
359
+ }
360
+ const { node } = astPath;
361
+ if (node.declaration.type === 'Identifier') {
362
+ exportedIdentifier = node.declaration.name;
363
+ return false;
364
+ }
365
+ location = (_a = locationFromNode(node.declaration)) !== null && _a !== void 0 ? _a : locationFromNode(node);
366
+ return false;
367
+ },
368
+ });
369
+ if (exportedIdentifier) {
370
+ return findLocalSymbolLocation({ ast, name: exportedIdentifier });
371
+ }
372
+ return location;
373
+ };
374
+ const findLocalComponentDeclaration = ({ ast, name, }) => {
375
+ let declaration = null;
376
+ recast.types.visit(ast, {
377
+ visitVariableDeclarator(astPath) {
378
+ if (declaration) {
379
+ return false;
380
+ }
381
+ const { node } = astPath;
382
+ if (node.id.type === 'Identifier' && node.id.name === name) {
383
+ declaration = node;
384
+ return false;
385
+ }
386
+ this.traverse(astPath);
387
+ return undefined;
388
+ },
389
+ visitFunctionDeclaration(astPath) {
390
+ var _a;
391
+ if (declaration) {
392
+ return false;
393
+ }
394
+ const { node } = astPath;
395
+ if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
396
+ declaration = node;
397
+ return false;
398
+ }
399
+ this.traverse(astPath);
400
+ return undefined;
401
+ },
402
+ visitClassDeclaration(astPath) {
403
+ var _a;
404
+ if (declaration) {
405
+ return false;
406
+ }
407
+ const { node } = astPath;
408
+ if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
409
+ declaration = node;
410
+ return false;
411
+ }
412
+ this.traverse(astPath);
413
+ return undefined;
414
+ },
415
+ });
416
+ return declaration;
417
+ };
418
+ const getTopLevelReturnStatement = (statements) => {
419
+ const returnStatements = [];
420
+ for (const statement of statements) {
421
+ if (recast.types.namedTypes.ReturnStatement.check(statement)) {
422
+ returnStatements.push(statement);
423
+ }
424
+ }
425
+ if (returnStatements.length !== 1) {
426
+ return null;
427
+ }
428
+ const singleReturn = returnStatements[0];
429
+ const finalStatement = statements.at(-1);
430
+ if (singleReturn !== finalStatement) {
431
+ return null;
432
+ }
433
+ return singleReturn;
434
+ };
435
+ const getReturnedJsxFromFunction = (fn) => {
436
+ if (fn.type === 'ArrowFunctionExpression') {
437
+ if (fn.body.type === 'JSXElement' || fn.body.type === 'JSXFragment') {
438
+ return fn.body;
439
+ }
440
+ if (fn.body.type !== 'BlockStatement') {
441
+ return null;
442
+ }
443
+ const arrowReturnStatement = getTopLevelReturnStatement(fn.body.body);
444
+ if (!(arrowReturnStatement === null || arrowReturnStatement === void 0 ? void 0 : arrowReturnStatement.argument)) {
445
+ return null;
446
+ }
447
+ return arrowReturnStatement.argument.type === 'JSXElement' ||
448
+ arrowReturnStatement.argument.type === 'JSXFragment'
449
+ ? arrowReturnStatement.argument
450
+ : null;
451
+ }
452
+ if (fn.body.type !== 'BlockStatement') {
453
+ return null;
454
+ }
455
+ const returnStatement = getTopLevelReturnStatement(fn.body.body);
456
+ if (!(returnStatement === null || returnStatement === void 0 ? void 0 : returnStatement.argument)) {
457
+ return null;
458
+ }
459
+ return returnStatement.argument.type === 'JSXElement' ||
460
+ returnStatement.argument.type === 'JSXFragment'
461
+ ? returnStatement.argument
462
+ : null;
463
+ };
464
+ const findRenderMethod = (declaration) => {
465
+ const renderMethod = declaration.body.body.find((member) => {
466
+ return (member.type === 'ClassMethod' &&
467
+ member.kind === 'method' &&
468
+ member.key.type === 'Identifier' &&
469
+ member.key.name === 'render');
470
+ });
471
+ return (renderMethod === null || renderMethod === void 0 ? void 0 : renderMethod.type) === 'ClassMethod' ? renderMethod : null;
472
+ };
473
+ const getComponentRootNode = (declaration) => {
474
+ if (declaration.type === 'VariableDeclarator') {
475
+ if (!declaration.init ||
476
+ (declaration.init.type !== 'ArrowFunctionExpression' &&
477
+ declaration.init.type !== 'FunctionExpression')) {
478
+ return null;
479
+ }
480
+ return getReturnedJsxFromFunction(declaration.init);
481
+ }
482
+ if (declaration.type === 'ArrowFunctionExpression' ||
483
+ declaration.type === 'FunctionExpression' ||
484
+ declaration.type === 'FunctionDeclaration') {
485
+ return getReturnedJsxFromFunction(declaration);
486
+ }
487
+ if (declaration.type !== 'ClassDeclaration') {
488
+ return null;
489
+ }
490
+ const renderMethod = findRenderMethod(declaration);
491
+ if (!renderMethod) {
492
+ return null;
493
+ }
494
+ const returnStatement = getTopLevelReturnStatement(renderMethod.body.body);
495
+ if (!(returnStatement === null || returnStatement === void 0 ? void 0 : returnStatement.argument)) {
496
+ return null;
497
+ }
498
+ return returnStatement.argument.type === 'JSXElement' ||
499
+ returnStatement.argument.type === 'JSXFragment'
500
+ ? returnStatement.argument
501
+ : null;
502
+ };
503
+ const createSequenceElement = () => {
504
+ return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier('Sequence'), []), recast.types.builders.jsxClosingElement(recast.types.builders.jsxIdentifier('Sequence')), []);
505
+ };
506
+ const getDefaultExportDeclaration = (ast) => {
507
+ let declaration = null;
508
+ let identifierName = null;
509
+ recast.types.visit(ast, {
510
+ visitExportDefaultDeclaration(astPath) {
511
+ if (declaration || identifierName) {
512
+ return false;
513
+ }
514
+ const { node } = astPath;
515
+ if (node.declaration.type === 'Identifier') {
516
+ identifierName = node.declaration.name;
517
+ return false;
518
+ }
519
+ declaration = node.declaration;
520
+ return false;
521
+ },
522
+ });
523
+ if (identifierName) {
524
+ return findLocalComponentDeclaration({ ast, name: identifierName });
525
+ }
526
+ return declaration;
527
+ };
528
+ const getDeclarationByExportName = ({ ast, exportName, }) => {
529
+ if (exportName === 'default') {
530
+ return getDefaultExportDeclaration(ast);
531
+ }
532
+ return findLocalComponentDeclaration({ ast, name: exportName });
533
+ };
534
+ const canAddSequenceToComponent = ({ ast, exportName, }) => {
535
+ const declaration = getDeclarationByExportName({ ast, exportName });
536
+ if (!declaration) {
537
+ return false;
538
+ }
539
+ const rootNode = getComponentRootNode(declaration);
540
+ if (!rootNode) {
541
+ return false;
542
+ }
543
+ if (rootNode.type === 'JSXElement') {
544
+ if (rootNode.openingElement.selfClosing) {
545
+ return false;
546
+ }
547
+ if (!rootNode.children) {
548
+ return false;
549
+ }
550
+ rootNode.children.push(createSequenceElement());
551
+ try {
552
+ recast.print(ast);
553
+ return true;
554
+ }
555
+ catch (_a) {
556
+ return false;
557
+ }
558
+ }
559
+ if (!rootNode.children) {
560
+ return false;
561
+ }
562
+ rootNode.children.push(createSequenceElement());
563
+ try {
564
+ recast.print(ast);
565
+ return true;
566
+ }
567
+ catch (_b) {
568
+ return false;
569
+ }
570
+ };
571
+ const getComponentLocationInFile = async ({ remotionRoot, fileName, exportName, }) => {
572
+ var _a, _b;
573
+ const input = await readSourceFile({ remotionRoot, fileName });
574
+ const ast = (0, parse_ast_1.parseAst)(input);
575
+ const astForSequenceSimulation = (0, parse_ast_1.parseAst)(input);
576
+ const location = exportName === 'default'
577
+ ? findDefaultExportLocation(ast)
578
+ : findLocalSymbolLocation({ ast, name: exportName });
579
+ const canAddSequence = canAddSequenceToComponent({
580
+ ast: astForSequenceSimulation,
581
+ exportName,
582
+ });
583
+ return {
584
+ source: node_path_1.default.relative(remotionRoot, fileName),
585
+ line: (_a = location === null || location === void 0 ? void 0 : location.line) !== null && _a !== void 0 ? _a : 1,
586
+ column: (_b = location === null || location === void 0 ? void 0 : location.column) !== null && _b !== void 0 ? _b : 0,
587
+ canAddSequence,
588
+ };
589
+ };
590
+ const getComponentLocationRecursively = async ({ remotionRoot, fileName, exportName, visited, }) => {
591
+ const key = `${fileName}:${exportName}`;
592
+ if (visited.has(key)) {
593
+ throw new Error(`Could not resolve component export "${exportName}" in ${node_path_1.default.relative(remotionRoot, fileName)}`);
594
+ }
595
+ visited.add(key);
596
+ try {
597
+ const input = await readSourceFile({ remotionRoot, fileName });
598
+ const ast = (0, parse_ast_1.parseAst)(input);
599
+ const localDeclaration = getDeclarationByExportName({
600
+ ast,
601
+ exportName,
602
+ });
603
+ if (localDeclaration) {
604
+ return await getComponentLocationInFile({
605
+ remotionRoot,
606
+ fileName,
607
+ exportName,
608
+ });
609
+ }
610
+ const reExportTargets = findReExportTargets({
611
+ ast,
612
+ exportName,
613
+ });
614
+ for (const target of reExportTargets) {
615
+ try {
616
+ const resolvedImportPath = resolveImportPath({
617
+ importPath: target.importPath,
618
+ fromFile: fileName,
619
+ });
620
+ return await getComponentLocationRecursively({
621
+ remotionRoot,
622
+ fileName: resolvedImportPath,
623
+ exportName: target.exportName,
624
+ visited,
625
+ });
626
+ }
627
+ catch (_a) {
628
+ continue;
629
+ }
630
+ }
631
+ if (reExportTargets.length > 0) {
632
+ throw new Error(`Could not resolve component export "${exportName}" in ${node_path_1.default.relative(remotionRoot, fileName)}`);
633
+ }
634
+ return await getComponentLocationInFile({
635
+ remotionRoot,
636
+ fileName,
637
+ exportName,
638
+ });
639
+ }
640
+ finally {
641
+ visited.delete(key);
642
+ }
643
+ };
644
+ const resolveCompositionComponent = async ({ remotionRoot, compositionFile, compositionId, }) => {
645
+ const compositionFileName = node_path_1.default.resolve(remotionRoot, compositionFile);
646
+ const input = await readSourceFile({
647
+ remotionRoot,
648
+ fileName: compositionFileName,
649
+ });
650
+ const ast = (0, parse_ast_1.parseAst)(input);
651
+ const compositionElement = findCompositionElement({ ast, compositionId });
652
+ if (!compositionElement) {
653
+ throw new Error(`Could not find composition "${compositionId}"`);
654
+ }
655
+ const lazyImportPath = getLazyImportPath(compositionElement);
656
+ if (lazyImportPath) {
657
+ const lazyComponentFile = resolveImportPath({
658
+ importPath: lazyImportPath,
659
+ fromFile: compositionFileName,
660
+ });
661
+ return getComponentLocationRecursively({
662
+ remotionRoot,
663
+ fileName: lazyComponentFile,
664
+ exportName: 'default',
665
+ visited: new Set(),
666
+ });
667
+ }
668
+ const componentName = getComponentIdentifier(compositionElement);
669
+ if (!componentName) {
670
+ throw new Error(`Could not find a component prop for composition "${compositionId}"`);
671
+ }
672
+ const importTarget = findImportTarget({ ast, componentName });
673
+ if (!importTarget) {
674
+ return getComponentLocationInFile({
675
+ remotionRoot,
676
+ fileName: compositionFileName,
677
+ exportName: componentName,
678
+ });
679
+ }
680
+ const importedComponentFile = resolveImportPath({
681
+ importPath: importTarget.importPath,
682
+ fromFile: compositionFileName,
683
+ });
684
+ return getComponentLocationRecursively({
685
+ remotionRoot,
686
+ fileName: importedComponentFile,
687
+ exportName: importTarget.exportName,
688
+ visited: new Set(),
689
+ });
690
+ };
691
+ exports.resolveCompositionComponent = resolveCompositionComponent;
package/dist/index.d.ts CHANGED
@@ -80,6 +80,10 @@ export declare const StudioServerInternals: {
80
80
  newContents: string;
81
81
  changesMade: import("./codemods/recast-mods").Change[];
82
82
  };
83
+ applyCodemodToFile: ({ filePath, codeMod, }: {
84
+ filePath: string;
85
+ codeMod: import("@remotion/studio-shared").RecastCodemod;
86
+ }) => Promise<string>;
83
87
  formatOutput: (tsContent: string) => Promise<string>;
84
88
  updateDefaultProps: ({ input, compositionId, newDefaultProps, enumPaths, }: {
85
89
  input: string;