@remotion/studio-server 4.0.484 → 4.0.486

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 (41) hide show
  1. package/dist/codemods/duplicate-composition.js +8 -0
  2. package/dist/codemods/recast-mods.js +246 -5
  3. package/dist/codemods/split-jsx-sequence.d.ts +14 -0
  4. package/dist/codemods/split-jsx-sequence.js +345 -0
  5. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +3 -1
  6. package/dist/codemods/update-sequence-props/update-sequence-props.js +406 -9
  7. package/dist/helpers/import-agnostic-node-path.js +30 -4
  8. package/dist/helpers/resolve-composition-component.d.ts +1 -0
  9. package/dist/helpers/resolve-composition-component.js +206 -9
  10. package/dist/preview-server/api-routes.js +2 -0
  11. package/dist/preview-server/routes/add-effect-keyframe.js +2 -2
  12. package/dist/preview-server/routes/add-effect.js +56 -53
  13. package/dist/preview-server/routes/add-keyframes.js +2 -2
  14. package/dist/preview-server/routes/add-sequence-keyframe.js +2 -2
  15. package/dist/preview-server/routes/apply-codemod.js +123 -101
  16. package/dist/preview-server/routes/apply-visual-control-change.js +83 -80
  17. package/dist/preview-server/routes/can-update-sequence-props.d.ts +13 -1
  18. package/dist/preview-server/routes/can-update-sequence-props.js +101 -7
  19. package/dist/preview-server/routes/delete-effect.js +83 -80
  20. package/dist/preview-server/routes/delete-jsx-node.js +74 -71
  21. package/dist/preview-server/routes/delete-keyframes.js +2 -2
  22. package/dist/preview-server/routes/duplicate-effect.js +77 -74
  23. package/dist/preview-server/routes/duplicate-jsx-node.js +53 -50
  24. package/dist/preview-server/routes/insert-element.js +2 -2
  25. package/dist/preview-server/routes/insert-jsx-element.js +53 -4
  26. package/dist/preview-server/routes/move-keyframes.js +2 -2
  27. package/dist/preview-server/routes/paste-effects.js +59 -56
  28. package/dist/preview-server/routes/reorder-effect.js +55 -52
  29. package/dist/preview-server/routes/reorder-sequence.js +55 -52
  30. package/dist/preview-server/routes/save-effect-props.js +2 -2
  31. package/dist/preview-server/routes/save-sequence-props.d.ts +3 -1
  32. package/dist/preview-server/routes/save-sequence-props.js +208 -24
  33. package/dist/preview-server/routes/source-file-write-queue.d.ts +1 -0
  34. package/dist/preview-server/routes/source-file-write-queue.js +11 -0
  35. package/dist/preview-server/routes/split-jsx-sequence.d.ts +3 -0
  36. package/dist/preview-server/routes/split-jsx-sequence.js +66 -0
  37. package/dist/preview-server/routes/update-default-props.js +58 -55
  38. package/dist/preview-server/routes/update-effect-keyframe-settings.js +2 -2
  39. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +2 -2
  40. package/dist/preview-server/undo-stack.d.ts +7 -1
  41. package/package.json +6 -6
@@ -85,9 +85,396 @@ const snapshotTopLevelAttrs = (node) => {
85
85
  }
86
86
  return result;
87
87
  };
88
- const updateSequencePropsNode = ({ node, updates, schema, }) => {
88
+ const escapeJsxText = (value) => {
89
+ return value
90
+ .replace(/&/g, '&')
91
+ .replace(/</g, '&lt;')
92
+ .replace(/>/g, '&gt;')
93
+ .replace(/{/g, '&#123;')
94
+ .replace(/}/g, '&#125;');
95
+ };
96
+ const findChildrenAttribute = (node) => {
97
+ var _a;
98
+ return (_a = node.attributes) === null || _a === void 0 ? void 0 : _a.find((attr) => {
99
+ return (attr.type === 'JSXAttribute' &&
100
+ attr.name.type === 'JSXIdentifier' &&
101
+ attr.name.name === 'children');
102
+ });
103
+ };
104
+ const updateJsxTextContent = ({ jsxElement, value, }) => {
105
+ const nextValue = String(value !== null && value !== void 0 ? value : '');
106
+ const staticChildrenAttribute = (0, can_update_sequence_props_1.getStaticJsxChildrenAttribute)(jsxElement.openingElement);
107
+ if (staticChildrenAttribute) {
108
+ const childrenAttribute = findChildrenAttribute(jsxElement.openingElement);
109
+ if (!childrenAttribute) {
110
+ throw new Error('Expected static children attribute to exist');
111
+ }
112
+ childrenAttribute.value = b.stringLiteral(nextValue);
113
+ return staticChildrenAttribute.value;
114
+ }
115
+ if ((0, can_update_sequence_props_1.hasJsxChildrenAttribute)(jsxElement.openingElement)) {
116
+ throw new Error('Cannot update text content because the children attribute is not static text');
117
+ }
118
+ const staticTextContent = (0, can_update_sequence_props_1.getStaticJsxTextContent)(jsxElement);
119
+ if (!staticTextContent) {
120
+ throw new Error('Cannot update text content because JSX children are not static text');
121
+ }
122
+ const canRepresentAsJsxText = staticTextContent.kind === 'jsx-text' &&
123
+ !nextValue.includes('\n') &&
124
+ nextValue.trim() === nextValue;
125
+ if (canRepresentAsJsxText) {
126
+ jsxElement.children = [
127
+ b.jsxText(escapeJsxText(nextValue)),
128
+ ];
129
+ }
130
+ else {
131
+ jsxElement.children = [
132
+ b.jsxExpressionContainer(b.stringLiteral(nextValue)),
133
+ ];
134
+ }
135
+ return staticTextContent.value;
136
+ };
137
+ const collectTopLevelIdentifierNames = (ast) => {
138
+ const names = new Set();
139
+ recast.types.visit(ast, {
140
+ visitIdentifier(path) {
141
+ names.add(path.node.name);
142
+ this.traverse(path);
143
+ },
144
+ });
145
+ return names;
146
+ };
147
+ const toSafeIdentifier = (value) => {
148
+ const sanitized = value.replace(/[^a-zA-Z0-9_$]/g, '');
149
+ if (!sanitized) {
150
+ return 'loadGoogleFont';
151
+ }
152
+ return /^[a-zA-Z_$]/.test(sanitized) ? sanitized : `_${sanitized}`;
153
+ };
154
+ const getSafeLoadFontIdentifier = ({ font, usedNames, }) => {
155
+ const baseName = toSafeIdentifier(`load${font.importName}`);
156
+ if (!usedNames.has(baseName)) {
157
+ usedNames.add(baseName);
158
+ return baseName;
159
+ }
160
+ let index = 2;
161
+ while (usedNames.has(`${baseName}${index}`)) {
162
+ index++;
163
+ }
164
+ const name = `${baseName}${index}`;
165
+ usedNames.add(name);
166
+ return name;
167
+ };
168
+ const getImportedLoadFontIdentifier = ({ ast, font, }) => {
169
+ var _a;
170
+ var _b, _c;
171
+ const moduleName = `@remotion/google-fonts/${font.importName}`;
172
+ for (const statement of ast.program.body) {
173
+ if (statement.type !== 'ImportDeclaration' ||
174
+ statement.source.value !== moduleName) {
175
+ continue;
176
+ }
177
+ for (const specifier of (_b = statement.specifiers) !== null && _b !== void 0 ? _b : []) {
178
+ if (specifier.type === 'ImportSpecifier' &&
179
+ specifier.imported.type === 'Identifier' &&
180
+ specifier.imported.name === 'loadFont') {
181
+ return (_c = (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _c !== void 0 ? _c : 'loadFont';
182
+ }
183
+ }
184
+ }
185
+ return null;
186
+ };
187
+ const getInsertIndexAfterImportsOrDirectives = (ast) => {
188
+ const lastImportIndex = ast.program.body.reduce((lastIndex, statement, index) => {
189
+ return statement.type === 'ImportDeclaration' ? index : lastIndex;
190
+ }, -1);
191
+ if (lastImportIndex !== -1) {
192
+ return lastImportIndex + 1;
193
+ }
194
+ return ast.program.body.findIndex((statement) => {
195
+ return !(statement.type === 'ExpressionStatement' &&
196
+ 'directive' in statement &&
197
+ statement.directive);
198
+ });
199
+ };
200
+ const insertAfterImportsOrDirectives = (ast, statement) => {
201
+ const insertIndex = getInsertIndexAfterImportsOrDirectives(ast);
202
+ ast.program.body.splice(insertIndex === -1 ? ast.program.body.length : insertIndex, 0, statement);
203
+ };
204
+ const ensureLoadFontImport = ({ ast, font, usedNames, }) => {
205
+ var _a;
206
+ var _b;
207
+ const existing = getImportedLoadFontIdentifier({ ast, font });
208
+ if (existing) {
209
+ return existing;
210
+ }
211
+ const moduleName = `@remotion/google-fonts/${font.importName}`;
212
+ const localName = getSafeLoadFontIdentifier({ font, usedNames });
213
+ const specifier = b.importSpecifier(b.identifier('loadFont'), b.identifier(localName));
214
+ for (const statement of ast.program.body) {
215
+ if (statement.type === 'ImportDeclaration' &&
216
+ statement.source.value === moduleName &&
217
+ !((_a = statement.specifiers) === null || _a === void 0 ? void 0 : _a.some((existingSpecifier) => existingSpecifier.type === 'ImportNamespaceSpecifier'))) {
218
+ statement.specifiers = [
219
+ ...((_b = statement.specifiers) !== null && _b !== void 0 ? _b : []),
220
+ specifier,
221
+ ];
222
+ return localName;
223
+ }
224
+ }
225
+ const declaration = b.importDeclaration([specifier], b.stringLiteral(moduleName));
226
+ insertAfterImportsOrDirectives(ast, declaration);
227
+ return localName;
228
+ };
229
+ const getStringArrayObjectProperty = ({ node, key, }) => {
230
+ if (node.type !== 'ObjectExpression') {
231
+ return null;
232
+ }
233
+ const property = node.properties.find((prop) => {
234
+ return (prop.type === 'ObjectProperty' &&
235
+ prop.key.type === 'Identifier' &&
236
+ prop.key.name === key);
237
+ });
238
+ if (!property || property.type !== 'ObjectProperty') {
239
+ return null;
240
+ }
241
+ if (property.value.type !== 'ArrayExpression') {
242
+ return null;
243
+ }
244
+ const values = [];
245
+ for (const element of property.value.elements) {
246
+ if (!element || element.type !== 'StringLiteral') {
247
+ return null;
248
+ }
249
+ values.push(element.value);
250
+ }
251
+ return values;
252
+ };
253
+ const arraysEqual = (a, bValues) => {
254
+ return (a.length === bValues.length &&
255
+ a.every((value, index) => value === bValues[index]));
256
+ };
257
+ const isMatchingLoadFontCall = ({ statement, localName, font, }) => {
258
+ if (statement.type !== 'ExpressionStatement' ||
259
+ statement.expression.type !== 'CallExpression' ||
260
+ statement.expression.callee.type !== 'Identifier' ||
261
+ statement.expression.callee.name !== localName) {
262
+ return false;
263
+ }
264
+ const [style, options] = statement.expression.arguments;
265
+ if ((style === null || style === void 0 ? void 0 : style.type) !== 'StringLiteral' || style.value !== font.style) {
266
+ return false;
267
+ }
268
+ if (!options || options.type !== 'ObjectExpression') {
269
+ return false;
270
+ }
271
+ const weights = getStringArrayObjectProperty({ node: options, key: 'weights' });
272
+ const subsets = getStringArrayObjectProperty({ node: options, key: 'subsets' });
273
+ return (weights !== null &&
274
+ subsets !== null &&
275
+ arraysEqual(weights, font.weights) &&
276
+ arraysEqual(subsets, font.subsets));
277
+ };
278
+ const hasTopLevelLoadFontCall = ({ ast, localName, font, }) => {
279
+ return ast.program.body.some((statement) => {
280
+ return isMatchingLoadFontCall({ statement, localName, font });
281
+ });
282
+ };
283
+ const getGoogleFontImportName = (moduleName) => {
284
+ const prefix = '@remotion/google-fonts/';
285
+ return moduleName.startsWith(prefix) ? moduleName.slice(prefix.length) : null;
286
+ };
287
+ const normalizeFontFamilyName = (fontFamily) => {
288
+ return fontFamily.toLowerCase().replace(/[^a-z0-9]/g, '');
289
+ };
290
+ const getPrimaryFontFamilyName = (fontFamily) => {
291
+ const trimmed = fontFamily.trim();
292
+ if (!trimmed) {
293
+ return null;
294
+ }
295
+ const quote = trimmed[0];
296
+ if (quote === '"' || quote === "'") {
297
+ const closingQuote = trimmed.indexOf(quote, 1);
298
+ return closingQuote === -1
299
+ ? trimmed.slice(1)
300
+ : trimmed.slice(1, closingQuote);
301
+ }
302
+ return trimmed.split(',')[0].trim();
303
+ };
304
+ const collectUsedFontFamilyNames = (ast) => {
305
+ const used = new Set();
306
+ const add = (fontFamily) => {
307
+ const primary = getPrimaryFontFamilyName(fontFamily);
308
+ if (primary) {
309
+ used.add(normalizeFontFamilyName(primary));
310
+ }
311
+ };
312
+ recast.types.visit(ast, {
313
+ visitObjectProperty(path) {
314
+ var _a;
315
+ const { node } = path;
316
+ if (node.key.type === 'Identifier' && node.key.name === 'fontFamily') {
317
+ if (node.value.type === 'StringLiteral') {
318
+ add(node.value.value);
319
+ }
320
+ if (node.value.type === 'TemplateLiteral' &&
321
+ node.value.expressions.length === 0 &&
322
+ node.value.quasis.length === 1) {
323
+ add((_a = node.value.quasis[0].value.cooked) !== null && _a !== void 0 ? _a : node.value.quasis[0].value.raw);
324
+ }
325
+ }
326
+ this.traverse(path);
327
+ },
328
+ visitJSXAttribute(path) {
329
+ var _a;
330
+ const { node } = path;
331
+ if (node.name.type === 'JSXIdentifier' &&
332
+ node.name.name === 'fontFamily' &&
333
+ ((_a = node.value) === null || _a === void 0 ? void 0 : _a.type) === 'StringLiteral') {
334
+ add(node.value.value);
335
+ }
336
+ this.traverse(path);
337
+ },
338
+ });
339
+ return used;
340
+ };
341
+ const isIdentifierImportedBySpecifier = ({ parent, name, }) => {
342
+ return (parent !== null &&
343
+ typeof parent === 'object' &&
344
+ 'type' in parent &&
345
+ parent.type === 'ImportSpecifier' &&
346
+ 'local' in parent &&
347
+ parent.local !== null &&
348
+ typeof parent.local === 'object' &&
349
+ 'type' in parent.local &&
350
+ parent.local.type === 'Identifier' &&
351
+ 'name' in parent.local &&
352
+ parent.local.name === name);
353
+ };
354
+ const hasNonImportIdentifierReference = ({ ast, name, }) => {
355
+ let hasReference = false;
356
+ recast.types.visit(ast, {
357
+ visitIdentifier(path) {
358
+ if (path.node.name !== name) {
359
+ this.traverse(path);
360
+ return;
361
+ }
362
+ if (isIdentifierImportedBySpecifier({ parent: path.parent.node, name })) {
363
+ this.traverse(path);
364
+ return;
365
+ }
366
+ hasReference = true;
367
+ return false;
368
+ },
369
+ });
370
+ return hasReference;
371
+ };
372
+ const googleFontLoadingComment = 'Remotion Studio generated Google Font loading';
373
+ const hasStudioGeneratedGoogleFontLoadingComment = (statement) => {
374
+ var _a;
375
+ return ((_a = statement.leadingComments) !== null && _a !== void 0 ? _a : []).some((comment) => comment.value.includes(googleFontLoadingComment));
376
+ };
377
+ const isTopLevelCallToIdentifier = ({ statement, localName, }) => {
378
+ return (statement.type === 'ExpressionStatement' &&
379
+ statement.expression.type === 'CallExpression' &&
380
+ statement.expression.callee.type === 'Identifier' &&
381
+ statement.expression.callee.name === localName);
382
+ };
383
+ const removeUnusedGoogleFontSourceEdits = (ast) => {
384
+ var _a;
385
+ var _b, _c;
386
+ const usedFonts = collectUsedFontFamilyNames(ast);
387
+ const loadFontLocalNamesToRemove = new Set();
388
+ for (const statement of ast.program.body) {
389
+ if (statement.type !== 'ImportDeclaration' ||
390
+ typeof statement.source.value !== 'string') {
391
+ continue;
392
+ }
393
+ const importName = getGoogleFontImportName(statement.source.value);
394
+ if (!importName) {
395
+ continue;
396
+ }
397
+ if (usedFonts.has(normalizeFontFamilyName(importName))) {
398
+ continue;
399
+ }
400
+ for (const specifier of (_b = statement.specifiers) !== null && _b !== void 0 ? _b : []) {
401
+ if (specifier.type === 'ImportSpecifier' &&
402
+ specifier.imported.type === 'Identifier' &&
403
+ specifier.imported.name === 'loadFont') {
404
+ loadFontLocalNamesToRemove.add((_c = (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _c !== void 0 ? _c : 'loadFont');
405
+ }
406
+ }
407
+ }
408
+ if (loadFontLocalNamesToRemove.size === 0) {
409
+ return;
410
+ }
411
+ ast.program.body = ast.program.body.filter((statement) => {
412
+ for (const localName of loadFontLocalNamesToRemove) {
413
+ if (isTopLevelCallToIdentifier({ statement, localName }) &&
414
+ hasStudioGeneratedGoogleFontLoadingComment(statement)) {
415
+ return false;
416
+ }
417
+ }
418
+ return true;
419
+ });
420
+ ast.program.body = ast.program.body.filter((statement) => {
421
+ var _a;
422
+ if (statement.type !== 'ImportDeclaration') {
423
+ return true;
424
+ }
425
+ statement.specifiers = ((_a = statement.specifiers) !== null && _a !== void 0 ? _a : []).filter((specifier) => {
426
+ var _a, _b;
427
+ var _c, _d;
428
+ return !(specifier.type === 'ImportSpecifier' &&
429
+ specifier.imported.type === 'Identifier' &&
430
+ specifier.imported.name === 'loadFont' &&
431
+ loadFontLocalNamesToRemove.has((_c = (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _c !== void 0 ? _c : 'loadFont') &&
432
+ !hasNonImportIdentifierReference({
433
+ ast,
434
+ name: (_d = (_b = specifier.local) === null || _b === void 0 ? void 0 : _b.name) !== null && _d !== void 0 ? _d : 'loadFont',
435
+ }));
436
+ });
437
+ return statement.specifiers.length > 0;
438
+ });
439
+ };
440
+ const insertLoadFontCall = ({ ast, font, localName, }) => {
441
+ if (hasTopLevelLoadFontCall({ ast, localName, font })) {
442
+ return;
443
+ }
444
+ const call = b.expressionStatement(b.callExpression(b.identifier(localName), [
445
+ b.stringLiteral(font.style),
446
+ b.objectExpression([
447
+ b.objectProperty(b.identifier('weights'), b.arrayExpression(font.weights.map((weight) => b.stringLiteral(weight)))),
448
+ b.objectProperty(b.identifier('subsets'), b.arrayExpression(font.subsets.map((subset) => b.stringLiteral(subset)))),
449
+ ]),
450
+ ]));
451
+ call.comments = [b.commentLine(` ${googleFontLoadingComment}`)];
452
+ insertAfterImportsOrDirectives(ast, call);
453
+ };
454
+ const applyGoogleFontSourceEdits = ({ ast, updates, }) => {
455
+ const fonts = new Map();
456
+ let hasFontFamilyUpdate = false;
457
+ for (const update of updates) {
458
+ if (update.key === 'style.fontFamily') {
459
+ hasFontFamilyUpdate = true;
460
+ }
461
+ if (update.googleFont) {
462
+ fonts.set(update.googleFont.importName, update.googleFont);
463
+ }
464
+ }
465
+ const usedNames = collectTopLevelIdentifierNames(ast);
466
+ for (const font of fonts.values()) {
467
+ const localName = ensureLoadFontImport({ ast, font, usedNames });
468
+ insertLoadFontCall({ ast, font, localName });
469
+ }
470
+ if (hasFontFamilyUpdate) {
471
+ removeUnusedGoogleFontSourceEdits(ast);
472
+ }
473
+ };
474
+ const updateSequencePropsNode = ({ jsxElement, updates, schema, }) => {
89
475
  var _a, _b, _c;
90
476
  var _d, _e;
477
+ const node = jsxElement.openingElement;
91
478
  const logLine = (_d = (_a = node.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _d !== void 0 ? _d : 1;
92
479
  const oldValueStrings = [];
93
480
  const initialAttrs = snapshotTopLevelAttrs(node);
@@ -97,8 +484,14 @@ const updateSequencePropsNode = ({ node, updates, schema, }) => {
97
484
  }));
98
485
  for (const { key, value, defaultValue } of updates) {
99
486
  let oldValueString = '';
100
- const isDefault = defaultValue !== null &&
101
- JSON.stringify(value) === JSON.stringify(defaultValue);
487
+ if (key === 'children') {
488
+ oldValueString = updateJsxTextContent({ jsxElement, value });
489
+ oldValueStrings.push(oldValueString);
490
+ continue;
491
+ }
492
+ const isDefault = (defaultValue === null && value === undefined) ||
493
+ (defaultValue !== null &&
494
+ JSON.stringify(value) === JSON.stringify(defaultValue));
102
495
  const dotIndex = key.indexOf('.');
103
496
  const isNested = dotIndex !== -1;
104
497
  const parentKey = isNested ? key.slice(0, dotIndex) : key;
@@ -197,15 +590,16 @@ const updateSequencePropsNode = ({ node, updates, schema, }) => {
197
590
  };
198
591
  const updateSequencePropsAst = ({ input, nodePath, updates, schema, }) => {
199
592
  const ast = (0, parse_ast_1.parseAst)(input);
200
- const node = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, nodePath);
201
- if (!node) {
593
+ const jsxElement = (0, can_update_sequence_props_1.findJsxElementNodeAtNodePath)(ast, nodePath);
594
+ if (!jsxElement) {
202
595
  throw new Error('Could not find a JSX element at the specified line to update');
203
596
  }
204
597
  const { oldValueStrings, logLine, removedProps } = updateSequencePropsNode({
205
- node,
598
+ jsxElement,
206
599
  updates,
207
600
  schema,
208
601
  });
602
+ applyGoogleFontSourceEdits({ ast, updates });
209
603
  return {
210
604
  serialized: (0, parse_ast_1.serializeAst)(ast),
211
605
  oldValueStrings,
@@ -216,13 +610,16 @@ const updateSequencePropsAst = ({ input, nodePath, updates, schema, }) => {
216
610
  exports.updateSequencePropsAst = updateSequencePropsAst;
217
611
  const updateMultipleSequenceProps = async ({ input, changes, prettierConfigOverride, }) => {
218
612
  const ast = (0, parse_ast_1.parseAst)(input);
613
+ const allUpdates = [];
219
614
  const results = changes.map(({ nodePath, updates, schema }) => {
220
- const node = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, nodePath);
221
- if (!node) {
615
+ const jsxElement = (0, can_update_sequence_props_1.findJsxElementNodeAtNodePath)(ast, nodePath);
616
+ if (!jsxElement) {
222
617
  throw new Error('Could not find a JSX element at the specified line to update');
223
618
  }
224
- return updateSequencePropsNode({ node, updates, schema });
619
+ allUpdates.push(...updates);
620
+ return updateSequencePropsNode({ jsxElement, updates, schema });
225
621
  });
622
+ applyGoogleFontSourceEdits({ ast, updates: allUpdates });
226
623
  const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
227
624
  input: (0, parse_ast_1.serializeAst)(ast),
228
625
  prettierConfigOverride,
@@ -49,6 +49,26 @@ const getUseCurrentFrameLocalNames = (ast) => {
49
49
  }
50
50
  return names;
51
51
  };
52
+ const getGoogleFontLoadFontLocalNames = (ast) => {
53
+ var _a;
54
+ var _b;
55
+ const names = new Set();
56
+ for (const statement of ast.program.body) {
57
+ if (statement.type !== 'ImportDeclaration' ||
58
+ typeof statement.source.value !== 'string' ||
59
+ !statement.source.value.startsWith('@remotion/google-fonts/')) {
60
+ continue;
61
+ }
62
+ for (const specifier of statement.specifiers) {
63
+ if (specifier.type === 'ImportSpecifier' &&
64
+ specifier.imported.type === 'Identifier' &&
65
+ specifier.imported.name === 'loadFont') {
66
+ names.add((_b = (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'loadFont');
67
+ }
68
+ }
69
+ }
70
+ return names;
71
+ };
52
72
  const isUseCurrentFrameCall = (node, useCurrentFrameLocalNames) => {
53
73
  return ((node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' &&
54
74
  node.callee.type === 'Identifier' &&
@@ -63,13 +83,19 @@ const isUseCurrentFrameStatement = (node, useCurrentFrameLocalNames) => {
63
83
  }
64
84
  return isUseCurrentFrameCall(node.declarations[0].init, useCurrentFrameLocalNames);
65
85
  };
86
+ const isGoogleFontLoadFontStatement = (node, googleFontLoadFontLocalNames) => {
87
+ return (node.type === 'ExpressionStatement' &&
88
+ node.expression.type === 'CallExpression' &&
89
+ node.expression.callee.type === 'Identifier' &&
90
+ googleFontLoadFontLocalNames.has(node.expression.callee.name));
91
+ };
66
92
  const getIgnoredNodePredicate = (ast) => {
67
93
  const useCurrentFrameLocalNames = getUseCurrentFrameLocalNames(ast);
94
+ const googleFontLoadFontLocalNames = getGoogleFontLoadFontLocalNames(ast);
68
95
  return (node, { parent, property }) => {
69
- if (parent.type === 'Program' &&
70
- property === 'body' &&
71
- node.type === 'ImportDeclaration') {
72
- return true;
96
+ if (parent.type === 'Program' && property === 'body') {
97
+ return (node.type === 'ImportDeclaration' ||
98
+ isGoogleFontLoadFontStatement(node, googleFontLoadFontLocalNames));
73
99
  }
74
100
  if (parent.type === 'BlockStatement' && property === 'body') {
75
101
  return isUseCurrentFrameStatement(node, useCurrentFrameLocalNames);
@@ -30,6 +30,7 @@ export declare const insertJsxElementIntoComposition: ({ remotionRoot, compositi
30
30
  width: number;
31
31
  height: number;
32
32
  };
33
+ durationInFrames?: number | null | undefined;
33
34
  name: string | null;
34
35
  position: InsertableCompositionElementPosition | null;
35
36
  } | null | undefined;