@remotion/studio-server 4.0.526 → 4.0.528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/codemods/apply-codemod-to-file.d.ts +2 -1
  2. package/dist/codemods/apply-codemod-to-file.js +142 -8
  3. package/dist/codemods/{delete-jsx-node.d.ts → delete-jsx-nodes.d.ts} +1 -10
  4. package/dist/codemods/delete-jsx-nodes.js +10 -0
  5. package/dist/codemods/paste-effects.d.ts +15 -1
  6. package/dist/codemods/paste-effects.js +3 -2
  7. package/dist/codemods/split-jsx-sequence.d.ts +14 -0
  8. package/dist/codemods/split-jsx-sequence.js +10 -3
  9. package/dist/codemods/update-effect-props/update-effect-props.d.ts +11 -3
  10. package/dist/codemods/update-effect-props/update-effect-props.js +17 -10
  11. package/dist/codemods/update-keyframes/update-keyframes.d.ts +31 -10
  12. package/dist/codemods/update-keyframes/update-keyframes.js +24 -7
  13. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +3 -6
  14. package/dist/codemods/update-sequence-props/update-sequence-props.js +16 -9
  15. package/dist/helpers/open-file-for-writing-without-symlinks.d.ts +6 -1
  16. package/dist/helpers/open-file-for-writing-without-symlinks.js +9 -6
  17. package/dist/helpers/resolve-composition-component.d.ts +1 -1
  18. package/dist/helpers/resolve-composition-component.js +5 -4
  19. package/dist/index.d.ts +0 -19
  20. package/dist/index.js +0 -6
  21. package/dist/preview-server/api-routes.js +8 -2
  22. package/dist/preview-server/hot-middleware/index.js +13 -46
  23. package/dist/preview-server/routes/add-effect.js +17 -8
  24. package/dist/preview-server/routes/apply-codemod.d.ts +0 -19
  25. package/dist/preview-server/routes/apply-codemod.js +24 -26
  26. package/dist/preview-server/routes/apply-visual-control-change.js +13 -65
  27. package/dist/preview-server/routes/can-update-default-props.d.ts +1 -1
  28. package/dist/preview-server/routes/can-update-default-props.js +3 -4
  29. package/dist/preview-server/routes/can-update-sequence-props.d.ts +0 -10
  30. package/dist/preview-server/routes/can-update-sequence-props.js +62 -495
  31. package/dist/preview-server/routes/delete-effect.js +15 -13
  32. package/dist/preview-server/routes/delete-jsx-nodes.d.ts +3 -0
  33. package/dist/preview-server/routes/{delete-jsx-node.js → delete-jsx-nodes.js} +23 -12
  34. package/dist/preview-server/routes/download-remote-asset.d.ts +5 -0
  35. package/dist/preview-server/routes/download-remote-asset.js +25 -20
  36. package/dist/preview-server/routes/duplicate-effect.js +12 -4
  37. package/dist/preview-server/routes/duplicate-jsx-node.js +15 -4
  38. package/dist/preview-server/routes/element-install-plan.d.ts +1 -1
  39. package/dist/preview-server/routes/find-in-file.d.ts +9 -1
  40. package/dist/preview-server/routes/find-in-file.js +3 -4
  41. package/dist/preview-server/routes/insert-basic-captions.d.ts +3 -0
  42. package/dist/preview-server/routes/insert-basic-captions.js +119 -0
  43. package/dist/preview-server/routes/insert-element.js +399 -280
  44. package/dist/preview-server/routes/install-dependency.js +14 -4
  45. package/dist/preview-server/routes/prepare-element-install.js +3 -0
  46. package/dist/preview-server/routes/reorder-effect.js +12 -5
  47. package/dist/preview-server/routes/reorder-sequence.js +10 -5
  48. package/dist/preview-server/routes/replace-video-source.d.ts +3 -0
  49. package/dist/preview-server/routes/replace-video-source.js +81 -0
  50. package/dist/preview-server/routes/save-sequence-props.js +8 -28
  51. package/dist/preview-server/routes/split-jsx-sequence.js +82 -42
  52. package/dist/preview-server/routes/split-video-from-audio.js +9 -4
  53. package/dist/preview-server/routes/subscribe-to-sequence-props.js +6 -10
  54. package/dist/preview-server/routes/update-config.js +38 -2
  55. package/dist/preview-server/routes/update-default-props.js +12 -8
  56. package/dist/preview-server/routes/wrap-jsx-node.d.ts +3 -0
  57. package/dist/preview-server/routes/wrap-jsx-node.js +97 -0
  58. package/dist/preview-server/studio-protocol/handle-discovery.js +1 -1
  59. package/dist/preview-server/studio-protocol/handle-element-library.js +3 -3
  60. package/dist/preview-server/undo-stack.d.ts +2 -1
  61. package/dist/preview-server/undo-stack.js +19 -0
  62. package/dist/routes.js +2 -0
  63. package/package.json +8 -8
  64. package/dist/canvas-capture/generate-canvas-capture-composition.d.ts +0 -14
  65. package/dist/canvas-capture/generate-canvas-capture-composition.js +0 -239
  66. package/dist/codemods/add-effect.d.ts +0 -1
  67. package/dist/codemods/add-effect.js +0 -8
  68. package/dist/codemods/apply-visual-control.d.ts +0 -8
  69. package/dist/codemods/apply-visual-control.js +0 -89
  70. package/dist/codemods/delete-effect.d.ts +0 -1
  71. package/dist/codemods/delete-effect.js +0 -6
  72. package/dist/codemods/delete-jsx-node.js +0 -17
  73. package/dist/codemods/duplicate-composition.d.ts +0 -2
  74. package/dist/codemods/duplicate-composition.js +0 -64
  75. package/dist/codemods/duplicate-effect.d.ts +0 -1
  76. package/dist/codemods/duplicate-effect.js +0 -6
  77. package/dist/codemods/duplicate-jsx-node.d.ts +0 -25
  78. package/dist/codemods/duplicate-jsx-node.js +0 -26
  79. package/dist/codemods/format-file-content.d.ts +0 -7
  80. package/dist/codemods/format-file-content.js +0 -80
  81. package/dist/codemods/format-inline-content.d.ts +0 -18
  82. package/dist/codemods/format-inline-content.js +0 -78
  83. package/dist/codemods/recast-mods.d.ts +0 -13
  84. package/dist/codemods/recast-mods.js +0 -902
  85. package/dist/codemods/reorder-effect.d.ts +0 -1
  86. package/dist/codemods/reorder-effect.js +0 -5
  87. package/dist/codemods/reorder-sequence.d.ts +0 -1
  88. package/dist/codemods/reorder-sequence.js +0 -5
  89. package/dist/codemods/simple-diff.d.ts +0 -5
  90. package/dist/codemods/simple-diff.js +0 -39
  91. package/dist/codemods/split-video-from-audio.d.ts +0 -1
  92. package/dist/codemods/split-video-from-audio.js +0 -5
  93. package/dist/codemods/update-default-props.d.ts +0 -1
  94. package/dist/codemods/update-default-props.js +0 -6
  95. package/dist/codemods/update-inline-caption-patches.d.ts +0 -1
  96. package/dist/codemods/update-inline-caption-patches.js +0 -5
  97. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +0 -1
  98. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +0 -7
  99. package/dist/preview-server/routes/delete-jsx-node.d.ts +0 -3
  100. package/dist/preview-server/routes/update-public-license.d.ts +0 -11
  101. package/dist/preview-server/routes/update-public-license.js +0 -97
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateDefaultPropsHandler = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
+ const codemods_1 = require("@remotion/codemods");
5
6
  const renderer_1 = require("@remotion/renderer");
6
- const update_default_props_1 = require("../../codemods/update-default-props");
7
7
  const file_watcher_1 = require("../../file-watcher");
8
8
  const format_log_file_location_1 = require("../format-log-file-location");
9
9
  const project_info_1 = require("../project-info");
@@ -13,6 +13,8 @@ const can_update_default_props_1 = require("./can-update-default-props");
13
13
  const source_file_write_queue_1 = require("./source-file-write-queue");
14
14
  const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumPaths }, remotionRoot, entryPoint, logLevel, }) => {
15
15
  return (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
16
+ var _a;
17
+ var _b;
16
18
  try {
17
19
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[update-default-props] Received request for compositionId="${compositionId}"`);
18
20
  const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
@@ -21,16 +23,18 @@ const updateDefaultPropsHandler = ({ input: { compositionId, defaultProps, enumP
21
23
  }
22
24
  (0, can_update_default_props_1.checkIfTypeScriptFile)(projectInfo.rootFile);
23
25
  const fileContents = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
24
- const logLine = (0, update_default_props_1.getCompositionDefaultPropsLine)({
25
- input: fileContents,
26
- compositionId,
27
- });
28
- const { output } = (0, update_default_props_1.updateDefaultProps)({
26
+ const result = (0, codemods_1.setCompositionDefaultProps)({
27
+ project: {
28
+ files: { [projectInfo.rootFile]: fileContents },
29
+ rootDir: remotionRoot,
30
+ },
31
+ compositionFile: projectInfo.rootFile,
29
32
  compositionId,
30
- input: fileContents,
31
- newDefaultProps: JSON.parse(defaultProps),
33
+ defaultProps: JSON.parse(defaultProps),
32
34
  enumPaths,
33
35
  });
36
+ const { logLine } = result;
37
+ const output = (_b = (_a = result.changes[0]) === null || _a === void 0 ? void 0 : _a.nextContents) !== null && _b !== void 0 ? _b : fileContents;
34
38
  (0, undo_stack_1.pushToUndoStack)({
35
39
  filePath: projectInfo.rootFile,
36
40
  oldContents: fileContents,
@@ -0,0 +1,3 @@
1
+ import type { WrapJsxNodeRequest, WrapJsxNodeResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const wrapJsxNodeHandler: ApiHandler<WrapJsxNodeRequest, WrapJsxNodeResponse>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapJsxNodeHandler = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const codemods_1 = require("@remotion/codemods");
6
+ const renderer_1 = require("@remotion/renderer");
7
+ const file_watcher_1 = require("../../file-watcher");
8
+ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
9
+ const format_log_file_location_1 = require("../format-log-file-location");
10
+ const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
11
+ const undo_stack_1 = require("../undo-stack");
12
+ const source_file_write_queue_1 = require("./source-file-write-queue");
13
+ const wrapJsxNodeHandler = ({ input: { fileName, nodePath, wrapper, width, height }, remotionRoot, logLevel, }) => {
14
+ return (0, source_file_write_queue_1.withSourceFileWriteQueue)(() => {
15
+ var _a;
16
+ try {
17
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
18
+ remotionRoot,
19
+ fileName,
20
+ action: 'modify',
21
+ });
22
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
23
+ const eligibility = (0, codemods_1.canWrapJsxNode)({ input: fileContents, nodePath });
24
+ if (wrapper === null) {
25
+ return Promise.resolve({
26
+ success: true,
27
+ ...eligibility,
28
+ nodePathMutation: null,
29
+ });
30
+ }
31
+ if (!eligibility.canWrap ||
32
+ (wrapper === 'HtmlInCanvas' && !eligibility.canWrapHtmlInCanvas)) {
33
+ throw new Error('This JSX element cannot be wrapped');
34
+ }
35
+ const result = (0, codemods_1.wrapJsxNode)({
36
+ project: { files: { [absolutePath]: fileContents }, rootDir: remotionRoot },
37
+ node: { filePath: absolutePath, nodePath },
38
+ wrapper,
39
+ width: width !== null && width !== void 0 ? width : 0,
40
+ height: height !== null && height !== void 0 ? height : 0,
41
+ });
42
+ const change = result.changes.find(({ filePath }) => filePath === absolutePath);
43
+ if ((change === null || change === void 0 ? void 0 : change.previousContents) !== fileContents ||
44
+ change.nextContents === null) {
45
+ throw new Error('Could not wrap JSX node');
46
+ }
47
+ const output = change.nextContents;
48
+ const remappings = result.nodePathRemappings.map(({ oldNodePath, newNodePath }) => ({ oldNodePath, newNodePath }));
49
+ const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([{ absolutePath, remappings }], null);
50
+ const line = result.logLine;
51
+ (0, undo_stack_1.pushTransactionToUndoStack)({
52
+ snapshots: [
53
+ {
54
+ filePath: absolutePath,
55
+ oldContents: fileContents,
56
+ newContents: null,
57
+ logLine: line,
58
+ nodePathRemappings: remappings,
59
+ },
60
+ ],
61
+ logLevel,
62
+ remotionRoot,
63
+ description: {
64
+ undoMessage: `↩️ Wrapping in ${wrapper}`,
65
+ redoMessage: `↪️ Wrapping in ${wrapper}`,
66
+ },
67
+ entryType: 'wrap-jsx-node',
68
+ suppressHmrOnFileRestore: false,
69
+ undoRedoNavigation: null,
70
+ });
71
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
72
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
73
+ file: absolutePath,
74
+ content: output,
75
+ originatorClientId: undefined,
76
+ metadata: { skipSequencePropsUpdate: true },
77
+ });
78
+ const locationLabel = (0, format_log_file_location_1.formatLogFileLocation)({
79
+ remotionRoot,
80
+ absolutePath,
81
+ line,
82
+ });
83
+ renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${(0, source_file_write_queue_1.getCodemodTimingPrefix)(logLevel)}${renderer_1.RenderInternals.chalk.blueBright(locationLabel)} Wrapped JSX in <${wrapper}>`);
84
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `[wrap-jsx-node] Wrote ${fileRelativeToRoot}`);
85
+ (0, undo_stack_1.printUndoHint)(logLevel);
86
+ return Promise.resolve({ success: true, ...eligibility, nodePathMutation });
87
+ }
88
+ catch (err) {
89
+ return Promise.resolve({
90
+ success: false,
91
+ reason: err.message,
92
+ stack: (_a = err.stack) !== null && _a !== void 0 ? _a : '',
93
+ });
94
+ }
95
+ });
96
+ };
97
+ exports.wrapJsxNodeHandler = wrapJsxNodeHandler;
@@ -105,7 +105,7 @@ const handleStudioProtocolDiscovery = ({ gitSource, liveEventsServer, remotionRo
105
105
  {
106
106
  type: 'install-element',
107
107
  payloadType: 'remotion-element',
108
- payloadVersions: [1],
108
+ payloadVersions: [1, 2],
109
109
  target: issuedInstallTarget === null || installTarget === null
110
110
  ? null
111
111
  : {
@@ -24,7 +24,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
24
24
  if (request.method !== 'POST') {
25
25
  (0, protocol_response_1.writeStudioProtocolError)({
26
26
  code: 'method-not-allowed',
27
- message: 'Use POST to add an Element catalog.',
27
+ message: 'Use POST to add an Element Library.',
28
28
  response,
29
29
  status: 405,
30
30
  });
@@ -75,7 +75,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
75
75
  catch (_c) {
76
76
  (0, protocol_response_1.writeStudioProtocolError)({
77
77
  code: 'invalid-url',
78
- message: 'The Element catalog URL must be an absolute HTTP or HTTPS URL.',
78
+ message: 'The Element Library URL must be an absolute HTTP or HTTPS URL.',
79
79
  response,
80
80
  status: 400,
81
81
  });
@@ -85,7 +85,7 @@ const handleStudioProtocolElementLibrary = async ({ configFile, focusStudioTab,
85
85
  if (displayName === '') {
86
86
  (0, protocol_response_1.writeStudioProtocolError)({
87
87
  code: 'invalid-display-name',
88
- message: 'The Element catalog display name must not be empty.',
88
+ message: 'The Element Library display name must not be empty.',
89
89
  response,
90
90
  status: 400,
91
91
  });
@@ -4,7 +4,7 @@ export interface UndoEntryDescription {
4
4
  undoMessage: string;
5
5
  redoMessage: string;
6
6
  }
7
- type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-node' | 'duplicate-jsx-node' | 'split-jsx-sequence' | 'split-video-from-audio' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-to-folder' | 'move-composition-or-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
7
+ type UndoEntryType = 'visual-control' | 'default-props' | 'sequence-props' | 'effect-props' | 'keyframe-add' | 'keyframe-delete' | 'add-effect' | 'delete-effect' | 'duplicate-effect' | 'paste-effects' | 'reorder-effect' | 'reorder-sequence' | 'delete-jsx-nodes' | 'duplicate-jsx-node' | 'wrap-jsx-node' | 'split-jsx-sequence' | 'split-video-from-audio' | 'insert-basic-captions' | 'replace-video-source' | 'insert-jsx-element' | 'delete-composition' | 'rename-composition' | 'update-composition-metadata' | 'new-composition' | 'duplicate-composition' | 'move-composition-or-folder' | 'new-folder' | 'delete-folder' | 'rename-folder';
8
8
  type UndoEntrySnapshot = {
9
9
  filePath: string;
10
10
  oldContents: string | null;
@@ -66,5 +66,6 @@ export declare function popUndo(): UndoResponse;
66
66
  export declare function popRedo(): RedoResponse;
67
67
  export declare function getUndoStack(): readonly UndoEntry[];
68
68
  export declare function getRedoStack(): readonly UndoEntry[];
69
+ export declare function discardLastUndoEntryAfterFailedCommit(): void;
69
70
  export declare function clearUndoStackForTests(): void;
70
71
  export {};
@@ -9,6 +9,7 @@ exports.popUndo = popUndo;
9
9
  exports.popRedo = popRedo;
10
10
  exports.getUndoStack = getUndoStack;
11
11
  exports.getRedoStack = getRedoStack;
12
+ exports.discardLastUndoEntryAfterFailedCommit = discardLastUndoEntryAfterFailedCommit;
12
13
  exports.clearUndoStackForTests = clearUndoStackForTests;
13
14
  const node_fs_1 = require("node:fs");
14
15
  const renderer_1 = require("@remotion/renderer");
@@ -392,6 +393,24 @@ function getUndoStack() {
392
393
  function getRedoStack() {
393
394
  return redoStack;
394
395
  }
396
+ function discardLastUndoEntryAfterFailedCommit() {
397
+ var _a;
398
+ const entry = undoStack.pop();
399
+ if (!entry) {
400
+ return;
401
+ }
402
+ for (const filePath of getEntryFilePaths(entry)) {
403
+ const count = (_a = suppressedWrites.get(filePath)) !== null && _a !== void 0 ? _a : 0;
404
+ if (count <= 1) {
405
+ suppressedWrites.delete(filePath);
406
+ }
407
+ else {
408
+ suppressedWrites.set(filePath, count - 1);
409
+ }
410
+ }
411
+ cleanupWatchers();
412
+ broadcastState();
413
+ }
395
414
  function clearUndoStackForTests() {
396
415
  undoStack.length = 0;
397
416
  redoStack.length = 0;
package/dist/routes.js CHANGED
@@ -210,6 +210,7 @@ const handleAddAsset = ({ req, res, search, publicDir, }) => {
210
210
  const fileDescriptor = (0, open_file_for_writing_without_symlinks_1.openFileForWritingWithoutSymlinks)({
211
211
  rootDirectory: publicDir,
212
212
  absolutePath,
213
+ exclusive: false,
213
214
  });
214
215
  const writeStream = (0, node_fs_1.createWriteStream)(absolutePath, {
215
216
  fd: fileDescriptor,
@@ -242,6 +243,7 @@ const handleUploadOutput = ({ req, res, search, remotionRoot, }) => {
242
243
  const fileDescriptor = (0, open_file_for_writing_without_symlinks_1.openFileForWritingWithoutSymlinks)({
243
244
  rootDirectory: remotionRoot,
244
245
  absolutePath,
246
+ exclusive: false,
245
247
  });
246
248
  const writeStream = (0, node_fs_1.createWriteStream)(absolutePath, {
247
249
  fd: fileDescriptor,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
4
4
  },
5
5
  "name": "@remotion/studio-server",
6
- "version": "4.0.526",
6
+ "version": "4.0.528",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@remotion/studio-protocol": "4.0.526",
26
+ "@remotion/studio-protocol": "4.0.528",
27
27
  "@babel/types": "7.24.0",
28
28
  "@babel/parser": "7.24.1",
29
29
  "@svgr/core": "8.1.0",
@@ -31,12 +31,12 @@
31
31
  "kiwi-schema": "0.5.0",
32
32
  "semver": "7.5.3",
33
33
  "zod": "4.5.4",
34
- "remotion": "4.0.526",
34
+ "remotion": "4.0.528",
35
35
  "recast": "0.23.21",
36
- "@remotion/bundler": "4.0.526",
37
- "@remotion/renderer": "4.0.526",
38
- "@remotion/studio-codemods": "4.0.526",
39
- "@remotion/studio-shared": "4.0.526",
36
+ "@remotion/bundler": "4.0.528",
37
+ "@remotion/renderer": "4.0.528",
38
+ "@remotion/codemods": "4.0.528",
39
+ "@remotion/studio-shared": "4.0.528",
40
40
  "memfs": "3.4.3",
41
41
  "open": "8.4.2"
42
42
  },
@@ -44,7 +44,7 @@
44
44
  "ast-types": "0.16.1",
45
45
  "react": "19.2.3",
46
46
  "@types/semver": "7.5.3",
47
- "@remotion/eslint-config-internal": "4.0.526",
47
+ "@remotion/eslint-config-internal": "4.0.528",
48
48
  "eslint": "9.19.0",
49
49
  "prettier": "3.8.1",
50
50
  "@types/node": "20.12.14",
@@ -1,14 +0,0 @@
1
- import type { CanvasCaptureData } from '@remotion/studio-shared';
2
- export declare const generateCanvasCaptureComposition: ({ componentName, compositionId, data, durationInFrames, fps, height, keyframeFps, videoFileName, videoHeight, videoWidth, width, }: {
3
- readonly componentName: string;
4
- readonly compositionId: string;
5
- readonly data: CanvasCaptureData;
6
- readonly durationInFrames: number;
7
- readonly fps: number;
8
- readonly height: number;
9
- readonly keyframeFps: number;
10
- readonly videoFileName: string;
11
- readonly videoHeight: number;
12
- readonly videoWidth: number;
13
- readonly width: number;
14
- }) => string;
@@ -1,239 +0,0 @@
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
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.generateCanvasCaptureComposition = void 0;
37
- const recast = __importStar(require("recast"));
38
- const customCursorRegex = /^\s*url\(/;
39
- const collapseMouseMovementsByFrame = ({ data, keyframeFps, }) => {
40
- const movements = [];
41
- for (const movement of data.mouseMovements) {
42
- if (movement.canvasX === null || movement.canvasY === null) {
43
- continue;
44
- }
45
- const framedMovement = {
46
- ...movement,
47
- frame: Math.ceil(movement.timeInSeconds * keyframeFps),
48
- };
49
- const previous = movements.at(-1);
50
- if ((previous === null || previous === void 0 ? void 0 : previous.frame) === framedMovement.frame) {
51
- movements[movements.length - 1] = framedMovement;
52
- }
53
- else {
54
- movements.push(framedMovement);
55
- }
56
- }
57
- return movements;
58
- };
59
- const getCursorName = (cursor) => {
60
- var _a;
61
- if (customCursorRegex.test(cursor)) {
62
- return 'custom';
63
- }
64
- return ((_a = cursor.split(',').at(-1)) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase()) || 'default';
65
- };
66
- const serialize = (value) => {
67
- if (typeof value === 'string') {
68
- return recast.prettyPrint(recast.types.builders.stringLiteral(value), {
69
- quote: 'single',
70
- }).code;
71
- }
72
- return JSON.stringify(value);
73
- };
74
- const serializeArray = (values, indentation) => {
75
- const items = values.map(serialize);
76
- const inline = `[${items.join(', ')}]`;
77
- if (indentation * 2 + inline.length + 1 <= 80) {
78
- return inline;
79
- }
80
- const lines = [];
81
- const numeric = values.every((value) => typeof value === 'number');
82
- for (const item of items) {
83
- const previous = lines.at(-1);
84
- if (numeric &&
85
- previous &&
86
- (indentation + 1) * 2 + previous.length + item.length + 2 <= 80) {
87
- lines[lines.length - 1] = `${previous} ${item},`;
88
- }
89
- else {
90
- lines.push(`${item},`);
91
- }
92
- }
93
- return [
94
- '[',
95
- ...lines.map((line) => `${'\t'.repeat(indentation + 1)}${line}`),
96
- `${'\t'.repeat(indentation)}]`,
97
- ].join('\n');
98
- };
99
- const generateCanvasCaptureComposition = ({ componentName, compositionId, data, durationInFrames, fps, height, keyframeFps, videoFileName, videoHeight, videoWidth, width, }) => {
100
- var _a;
101
- const movements = collapseMouseMovementsByFrame({ data, keyframeFps });
102
- if (movements.length === 0) {
103
- throw new Error('The Canvas Capture does not contain cursor movements');
104
- }
105
- const cursorKeyframes = movements.reduce((keyframes, movement) => {
106
- var _a;
107
- const value = getCursorName(movement.cursor);
108
- if (((_a = keyframes.at(-1)) === null || _a === void 0 ? void 0 : _a.value) !== value) {
109
- keyframes.push({ frame: movement.frame, value });
110
- }
111
- return keyframes;
112
- }, []);
113
- const positionKeyframes = [];
114
- for (const movement of movements) {
115
- const previous = positionKeyframes.at(-1);
116
- if (previous !== undefined && movement.frame - previous.frame > 1) {
117
- positionKeyframes.push({
118
- frame: movement.frame - 1,
119
- value: previous.value,
120
- });
121
- }
122
- positionKeyframes.push({
123
- frame: movement.frame,
124
- value: `${movement.canvasX}px ${movement.canvasY}px`,
125
- });
126
- }
127
- const scaleKeyframes = [
128
- { frame: 0, value: data.captureMetadata.density },
129
- ...data.pointerClicks.map((click) => ({
130
- frame: Math.ceil(click.timeInSeconds * keyframeFps),
131
- value: click.type === 'pointer-down'
132
- ? data.captureMetadata.density * 0.9
133
- : data.captureMetadata.density,
134
- })),
135
- ].reduce((keyframes, keyframe) => {
136
- var _a, _b;
137
- if (((_a = keyframes.at(-1)) === null || _a === void 0 ? void 0 : _a.frame) === keyframe.frame) {
138
- keyframes[keyframes.length - 1] = keyframe;
139
- }
140
- else if (((_b = keyframes.at(-1)) === null || _b === void 0 ? void 0 : _b.value) !== keyframe.value) {
141
- keyframes.push(keyframe);
142
- }
143
- return keyframes;
144
- }, []);
145
- const customCursor = (_a = movements.find((movement) => customCursorRegex.test(movement.cursor))) === null || _a === void 0 ? void 0 : _a.cursor;
146
- const cursorProp = cursorKeyframes.length === 1
147
- ? `cursor={${serialize(cursorKeyframes[0].value)}}`
148
- : `cursor={interpolate(
149
- frame,
150
- ${serializeArray(cursorKeyframes.map((keyframe) => keyframe.frame), 5)},
151
- ${serializeArray(cursorKeyframes.map((keyframe) => keyframe.value), 5)},
152
- {
153
- easing: Easing.step1,
154
- extrapolateLeft: 'clamp',
155
- extrapolateRight: 'clamp',
156
- },
157
- )}`;
158
- const scale = scaleKeyframes.length === 1
159
- ? serialize(scaleKeyframes[0].value)
160
- : `interpolate(
161
- frame,
162
- ${serializeArray(scaleKeyframes.map((keyframe) => keyframe.frame), 6)},
163
- ${serializeArray(scaleKeyframes.map((keyframe) => keyframe.value), 6)},
164
- {
165
- easing: Easing.step1,
166
- extrapolateLeft: 'clamp',
167
- extrapolateRight: 'clamp',
168
- },
169
- )`;
170
- const translate = positionKeyframes.length === 1
171
- ? serialize(positionKeyframes[0].value)
172
- : `interpolate(
173
- frame,
174
- ${serializeArray(positionKeyframes.map((keyframe) => keyframe.frame), 6)},
175
- ${serializeArray(positionKeyframes.map((keyframe) => keyframe.value), 6)},
176
- {
177
- extrapolateLeft: 'clamp',
178
- extrapolateRight: 'clamp',
179
- },
180
- )`;
181
- const previewComponentName = componentName.endsWith('Composition')
182
- ? `${componentName.slice(0, -'Composition'.length)}Preview`
183
- : `${componentName}Preview`;
184
- return `import {MacOSCursor} from '@remotion/mac-cursors';
185
- import {Video} from '@remotion/media';
186
- import {
187
- AbsoluteFill,
188
- Composition,
189
- Easing,
190
- interpolate,
191
- staticFile,
192
- useCurrentFrame,
193
- } from 'remotion';
194
-
195
- export const ${previewComponentName} = () => {
196
- const frame = useCurrentFrame();
197
-
198
- return (
199
- <AbsoluteFill
200
- style={{
201
- width: ${videoWidth},
202
- height: ${videoHeight},
203
- }}
204
- >
205
- <Video
206
- src={staticFile(${serialize(videoFileName)})}
207
- style={{
208
- position: 'absolute',
209
- }}
210
- />
211
- <MacOSCursor
212
- ${cursorProp}
213
- ${customCursor === undefined ? '' : `\t\t\t\tcustomCursor={${serialize(customCursor)}}\n`} style={{
214
- position: 'absolute',
215
- left: 0,
216
- top: 0,
217
- scale: ${scale},
218
- translate: ${translate},
219
- }}
220
- />
221
- </AbsoluteFill>
222
- );
223
- };
224
-
225
- export const ${componentName} = () => {
226
- return (
227
- <Composition
228
- id={${serialize(compositionId)}}
229
- component={${previewComponentName}}
230
- width={${width}}
231
- height={${height}}
232
- fps={${fps}}
233
- durationInFrames={${durationInFrames}}
234
- />
235
- );
236
- };
237
- `;
238
- };
239
- exports.generateCanvasCaptureComposition = generateCanvasCaptureComposition;
@@ -1 +0,0 @@
1
- export { addEffect, assertValidEffect, ensureEffectImport, makeConfigObjectExpression, } from '@remotion/studio-codemods';
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeConfigObjectExpression = exports.ensureEffectImport = exports.assertValidEffect = exports.addEffect = void 0;
4
- const studio_codemods_1 = require("@remotion/studio-codemods");
5
- Object.defineProperty(exports, "addEffect", { enumerable: true, get: function () { return studio_codemods_1.addEffect; } });
6
- Object.defineProperty(exports, "assertValidEffect", { enumerable: true, get: function () { return studio_codemods_1.assertValidEffect; } });
7
- Object.defineProperty(exports, "ensureEffectImport", { enumerable: true, get: function () { return studio_codemods_1.ensureEffectImport; } });
8
- Object.defineProperty(exports, "makeConfigObjectExpression", { enumerable: true, get: function () { return studio_codemods_1.makeConfigObjectExpression; } });
@@ -1,8 +0,0 @@
1
- import type { File } from '@babel/types';
2
- import { type ApplyVisualControlCodemod } from '@remotion/studio-shared';
3
- import type { ApplyCodeModReturnType, Change } from './recast-mods';
4
- export declare const applyVisualControl: ({ file, transformation, changesMade, }: {
5
- file: File;
6
- transformation: ApplyVisualControlCodemod;
7
- changesMade: Change[];
8
- }) => ApplyCodeModReturnType;
@@ -1,89 +0,0 @@
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
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.applyVisualControl = void 0;
37
- const studio_shared_1 = require("@remotion/studio-shared");
38
- const recast = __importStar(require("recast"));
39
- const parse_ast_1 = require("./parse-ast");
40
- const expectString = (node) => {
41
- if (node.type === 'StringLiteral') {
42
- return node.value;
43
- }
44
- if (node.type === 'TemplateLiteral') {
45
- if (node.expressions.length > 0) {
46
- throw new Error('applyVisualControl() must use a static identifier, the string may not be dynamic.');
47
- }
48
- return node.quasis[0].value.raw;
49
- }
50
- throw new Error('Expected a string literal');
51
- };
52
- const applyVisualControl = ({ file, transformation, changesMade, }) => {
53
- recast.types.visit(file.program, {
54
- visitCallExpression(path) {
55
- const { node } = path;
56
- if (node.type !== 'CallExpression') {
57
- throw new Error('Expected a call expression');
58
- }
59
- if (node.callee.type !== 'Identifier') {
60
- return this.traverse(path);
61
- }
62
- if (node.callee.name !== 'visualControl') {
63
- return this.traverse(path);
64
- }
65
- const firstArgument = node.arguments[0];
66
- const str = expectString(firstArgument);
67
- for (const change of transformation.changes) {
68
- if (change.id !== str) {
69
- continue;
70
- }
71
- let parsed;
72
- if (change.newValueIsUndefined) {
73
- parsed = (0, parse_ast_1.parseAst)('a = undefined').program
74
- .body[0].expression.right;
75
- }
76
- else {
77
- parsed = (0, parse_ast_1.parseAst)(`a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: JSON.parse(change.newValueSerialized), enumPaths: change.enumPaths })}`).program.body[0].expression.right;
78
- }
79
- node.arguments[1] = parsed;
80
- changesMade.push({
81
- description: `Applied visual control ${change.id}`,
82
- });
83
- }
84
- return this.traverse(path);
85
- },
86
- });
87
- return { newAst: file, changesMade };
88
- };
89
- exports.applyVisualControl = applyVisualControl;
@@ -1 +0,0 @@
1
- export { deleteEffect, deleteEffects, type EffectDeletionTarget, } from '@remotion/studio-codemods';