@remotion/cli 4.0.20 → 4.0.21

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 (31) hide show
  1. package/dist/config/image-format.d.ts +1 -1
  2. package/dist/config/index.d.ts +1 -1
  3. package/dist/config/log.d.ts +1 -1
  4. package/dist/editor/components/AssetSelectorItem.js +1 -1
  5. package/dist/editor/components/CompositionSelector.d.ts +3 -0
  6. package/dist/editor/components/CompositionSelector.js +39 -1
  7. package/dist/editor/components/CompositionSelectorItem.js +1 -1
  8. package/dist/editor/components/NewComposition/RemInput.d.ts +2 -2
  9. package/dist/editor/components/NewComposition/RemInputTypeColor.d.ts +1 -1
  10. package/dist/editor/components/NewComposition/RemTextarea.d.ts +1 -1
  11. package/dist/editor/components/QuickSwitcher/QuickSwitcherContent.js +27 -0
  12. package/dist/editor/components/RenderModal/human-readable-codec.d.ts +1 -1
  13. package/dist/editor/components/RenderQueue/RenderQueueCopyToClipboard.d.ts +6 -0
  14. package/dist/editor/components/RenderQueue/RenderQueueCopyToClipboard.js +51 -0
  15. package/dist/editor/components/RenderQueue/RenderQueueItem.js +2 -1
  16. package/dist/editor/components/RenderQueue/actions.d.ts +3 -0
  17. package/dist/editor/components/RenderQueue/actions.js +8 -1
  18. package/dist/editor/helpers/colors.d.ts +1 -1
  19. package/dist/get-cli-options.d.ts +2 -2
  20. package/dist/index.d.ts +13 -13
  21. package/dist/log.d.ts +4 -4
  22. package/dist/preview-server/api-routes.js +2 -0
  23. package/dist/preview-server/api-types.d.ts +2 -1
  24. package/dist/preview-server/dev-middleware/range-parser.d.ts +1 -1
  25. package/dist/preview-server/error-overlay/react-overlay/utils/get-file-source.js +3 -2
  26. package/dist/preview-server/render-queue/copy-still-to-clipboard.d.ts +1 -0
  27. package/dist/preview-server/render-queue/copy-still-to-clipboard.js +8 -0
  28. package/dist/preview-server/render-queue/job.d.ts +3 -0
  29. package/dist/preview-server/routes/copy-still-to-clipboard-handler.d.ts +3 -0
  30. package/dist/preview-server/routes/copy-still-to-clipboard-handler.js +17 -0
  31. package/package.json +8 -8
@@ -2,4 +2,4 @@ import type { StillImageFormat, VideoImageFormat } from '@remotion/renderer';
2
2
  export declare const setStillImageFormat: (format: StillImageFormat) => void;
3
3
  export declare const setVideoImageFormat: (format: VideoImageFormat) => void;
4
4
  export declare const getUserPreferredStillImageFormat: () => "png" | "jpeg" | "pdf" | "webp" | undefined;
5
- export declare const getUserPreferredVideoImageFormat: () => "none" | "png" | "jpeg" | undefined;
5
+ export declare const getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
@@ -297,7 +297,7 @@ export declare const ConfigInternals: {
297
297
  getShouldOutputImageSequence: (frameRange: FrameRange | null) => boolean;
298
298
  getDotEnvLocation: () => string | null;
299
299
  getUserPreferredStillImageFormat: () => "png" | "jpeg" | "pdf" | "webp" | undefined;
300
- getUserPreferredVideoImageFormat: () => "none" | "png" | "jpeg" | undefined;
300
+ getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
301
301
  getWebpackOverrideFn: () => WebpackOverrideFn;
302
302
  getWebpackCaching: () => boolean;
303
303
  getOutputLocation: () => string | null;
@@ -1 +1 @@
1
- export declare const getLogLevel: () => "error" | "verbose" | "info" | "warn", setLogLevel: (newLogLevel: "error" | "verbose" | "info" | "warn") => void;
1
+ export declare const getLogLevel: () => "verbose" | "info" | "warn" | "error", setLogLevel: (newLogLevel: "verbose" | "info" | "warn" | "error") => void;
@@ -108,7 +108,7 @@ const FolderTree = ({ item, level, name, parentFolder, tabIndex }) => {
108
108
  return ((0, jsx_runtime_1.jsxs)("div", { children: [item.folders.map((folder) => {
109
109
  return ((0, jsx_runtime_1.jsx)(exports.AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents }, folder.name));
110
110
  }), item.files.map((file) => {
111
- return ((0, jsx_runtime_1.jsx)(exports.AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents }, file.src));
111
+ return ((0, jsx_runtime_1.jsx)(exports.AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level, parentFolder: combinedParents }, file.src));
112
112
  })] }));
113
113
  };
114
114
  exports.FolderTree = FolderTree;
@@ -1,3 +1,6 @@
1
1
  import React from 'react';
2
2
  export declare const getKeysToExpand: (initialFolderName: string, parentFolderName: string | null, initial?: string[]) => string[];
3
+ export declare const compositionSelectorRef: React.RefObject<{
4
+ expandComposition: (compName: string) => void;
5
+ }>;
3
6
  export declare const CompositionSelector: React.FC;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CompositionSelector = exports.getKeysToExpand = void 0;
3
+ exports.CompositionSelector = exports.compositionSelectorRef = exports.getKeysToExpand = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
@@ -31,6 +31,7 @@ const getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
31
31
  return (0, exports.getKeysToExpand)(name, parent, initial);
32
32
  };
33
33
  exports.getKeysToExpand = getKeysToExpand;
34
+ exports.compositionSelectorRef = (0, react_1.createRef)();
34
35
  const CompositionSelector = () => {
35
36
  const { compositions, currentComposition, folders } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
36
37
  const [foldersExpanded, setFoldersExpanded] = (0, react_1.useState)((0, persist_open_folders_1.loadExpandedFolders)());
@@ -49,6 +50,43 @@ const CompositionSelector = () => {
49
50
  return foldersExpandedState;
50
51
  });
51
52
  }, []);
53
+ (0, react_1.useImperativeHandle)(exports.compositionSelectorRef, () => {
54
+ return {
55
+ expandComposition: (compName) => {
56
+ const compositionToExpand = compositions.find((c) => c.id === compName);
57
+ if (!compositionToExpand) {
58
+ return;
59
+ }
60
+ const { folderName, parentFolderName } = compositionToExpand;
61
+ if (folderName === null) {
62
+ return;
63
+ }
64
+ setFoldersExpanded((previousState) => {
65
+ var _a, _b, _c;
66
+ const foldersExpandedState = {
67
+ ...previousState,
68
+ };
69
+ let currentFolder = folderName;
70
+ let currentParentName = parentFolderName;
71
+ while (currentFolder) {
72
+ if (currentParentName === null || currentParentName === void 0 ? void 0 : currentParentName.includes('/')) {
73
+ const splittedParentName = currentParentName.split('/');
74
+ currentParentName = (_a = splittedParentName.pop()) !== null && _a !== void 0 ? _a : null;
75
+ }
76
+ const key = (0, persist_open_folders_1.openFolderKey)(currentFolder, currentParentName);
77
+ foldersExpandedState[key] = true;
78
+ const parentFolder = folders.find((f) => {
79
+ return f.name === currentParentName && currentParentName;
80
+ });
81
+ currentFolder = (_b = parentFolder === null || parentFolder === void 0 ? void 0 : parentFolder.name) !== null && _b !== void 0 ? _b : null;
82
+ currentParentName = (_c = parentFolder === null || parentFolder === void 0 ? void 0 : parentFolder.parent) !== null && _c !== void 0 ? _c : null;
83
+ }
84
+ (0, persist_open_folders_1.persistExpandedFolders)(foldersExpandedState);
85
+ return foldersExpandedState;
86
+ });
87
+ },
88
+ };
89
+ }, [compositions, folders]);
52
90
  const items = (0, react_1.useMemo)(() => {
53
91
  return (0, create_folder_tree_1.createFolderTree)(compositions, folders, foldersExpanded);
54
92
  }, [compositions, folders, foldersExpanded]);
@@ -91,6 +91,6 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
91
91
  })
92
92
  : null] }));
93
93
  }
94
- return ((0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("button", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, type: "button", title: item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.composition.id }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition }) })] }) }));
94
+ return ((0, jsx_runtime_1.jsx)(layout_1.Row, { align: "center", children: (0, jsx_runtime_1.jsxs)("button", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.composition.id }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition }) })] }) }));
95
95
  };
96
96
  exports.CompositionSelectorItem = CompositionSelectorItem;
@@ -12,6 +12,6 @@ export declare const getInputBorderColor: ({ status, isFocused, isHovered, }: {
12
12
  status: 'error' | 'warning' | 'ok';
13
13
  isFocused: boolean;
14
14
  isHovered: boolean;
15
- }) => "#ff3232" | "hsla(0, 0%, 100%, 0.15)" | "rgba(0, 0, 0, 0.6)" | "rgba(255, 255, 255, 0.05)" | "#f1c40f";
16
- export declare const RemotionInput: React.ForwardRefExoticComponent<Pick<Props, "key" | "status" | "rightAlign" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
15
+ }) => "hsla(0, 0%, 100%, 0.15)" | "rgba(0, 0, 0, 0.6)" | "rgba(255, 255, 255, 0.05)" | "#ff3232" | "#f1c40f";
16
+ export declare const RemotionInput: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | "rightAlign" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
17
17
  export {};
@@ -4,5 +4,5 @@ type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>
4
4
  status: RemInputStatus;
5
5
  name: string;
6
6
  };
7
- export declare const RemInputTypeColor: React.ForwardRefExoticComponent<Pick<Props, "key" | "status" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
7
+ export declare const RemInputTypeColor: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
8
8
  export {};
@@ -3,5 +3,5 @@ type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLTextAreaEleme
3
3
  status: 'error' | 'warning' | 'ok';
4
4
  };
5
5
  export declare const inputBaseStyle: React.CSSProperties;
6
- export declare const RemTextarea: React.ForwardRefExoticComponent<Pick<Props, "key" | "status" | keyof React.InputHTMLAttributes<HTMLTextAreaElement>> & React.RefAttributes<HTMLTextAreaElement>>;
6
+ export declare const RemTextarea: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLTextAreaElement>> & React.RefAttributes<HTMLTextAreaElement>>;
7
7
  export {};
@@ -9,6 +9,7 @@ const is_composition_still_1 = require("../../helpers/is-composition-still");
9
9
  const use_keybinding_1 = require("../../helpers/use-keybinding");
10
10
  const use_menu_structure_1 = require("../../helpers/use-menu-structure");
11
11
  const modals_1 = require("../../state/modals");
12
+ const CompositionSelector_1 = require("../CompositionSelector");
12
13
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
13
14
  const KeyboardShortcutsExplainer_1 = require("../KeyboardShortcutsExplainer");
14
15
  const layout_1 = require("../layout");
@@ -131,8 +132,16 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp }) => {
131
132
  title: c.id,
132
133
  type: 'composition',
133
134
  onSelected: () => {
135
+ var _a;
134
136
  selectComposition(c, true);
135
137
  setSelectedModal(null);
138
+ const selector = `.__remotion-composition[data-compname=${c.id}`;
139
+ (_a = CompositionSelector_1.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.expandComposition(c.id);
140
+ waitForElm(selector).then(() => {
141
+ var _a;
142
+ (_a = document
143
+ .querySelector(selector)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'center' });
144
+ });
136
145
  },
137
146
  compositionType: (0, is_composition_still_1.isCompositionStill)(c) ? 'still' : 'composition',
138
147
  };
@@ -272,3 +281,21 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp }) => {
272
281
  })) })] }));
273
282
  };
274
283
  exports.QuickSwitcherContent = QuickSwitcherContent;
284
+ function waitForElm(selector) {
285
+ return new Promise((resolve) => {
286
+ if (document.querySelector(selector)) {
287
+ resolve(document.querySelector(selector));
288
+ return;
289
+ }
290
+ const observer = new MutationObserver(() => {
291
+ if (document.querySelector(selector)) {
292
+ resolve(document.querySelector(selector));
293
+ observer.disconnect();
294
+ }
295
+ });
296
+ observer.observe(document.body, {
297
+ childList: true,
298
+ subtree: true,
299
+ });
300
+ });
301
+ }
@@ -1,2 +1,2 @@
1
1
  import type { Codec } from '@remotion/renderer';
2
- export declare const humanReadableCodec: (codec: Codec) => "AAC" | "MP3" | "GIF" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
2
+ export declare const humanReadableCodec: (codec: Codec) => "GIF" | "AAC" | "MP3" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ import type { RenderJob } from '../../../preview-server/render-queue/job';
3
+ export declare const supportsCopyingToClipboard: (job: RenderJob) => boolean;
4
+ export declare const RenderQueueCopyToClipboard: React.FC<{
5
+ job: RenderJob;
6
+ }>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderQueueCopyToClipboard = exports.supportsCopyingToClipboard = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const clipboard_1 = require("../../icons/clipboard");
7
+ const InlineAction_1 = require("../InlineAction");
8
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
9
+ const actions_1 = require("./actions");
10
+ const revealIconStyle = {
11
+ height: 12,
12
+ color: 'currentColor',
13
+ };
14
+ const supportsCopyingToClipboard = (job) => {
15
+ if (job.status !== 'done') {
16
+ return false;
17
+ }
18
+ if (job.type !== 'still') {
19
+ return false;
20
+ }
21
+ if (job.imageFormat === 'png') {
22
+ return true;
23
+ }
24
+ if (job.imageFormat === 'jpeg') {
25
+ return true;
26
+ }
27
+ return false;
28
+ };
29
+ exports.supportsCopyingToClipboard = supportsCopyingToClipboard;
30
+ const RenderQueueCopyToClipboard = ({ job, }) => {
31
+ const renderCopyAction = (0, react_1.useCallback)((color) => {
32
+ return (0, jsx_runtime_1.jsx)(clipboard_1.ClipboardIcon, { style: revealIconStyle, color: color });
33
+ }, []);
34
+ const onClick = (0, react_1.useCallback)(() => {
35
+ (0, actions_1.copyToClipboard)({ outName: job.outName })
36
+ .catch((err) => {
37
+ (0, NotificationCenter_1.sendErrorNotification)(`Could not copy to clipboard: ${err.message}`);
38
+ })
39
+ .then(() => {
40
+ var _a;
41
+ (_a = NotificationCenter_1.notificationCenter.current) === null || _a === void 0 ? void 0 : _a.addNotification({
42
+ content: 'Copied to clipboard',
43
+ created: Date.now(),
44
+ duration: 1000,
45
+ id: String(Math.random()),
46
+ });
47
+ });
48
+ }, [job.outName]);
49
+ return ((0, jsx_runtime_1.jsx)(InlineAction_1.InlineAction, { title: "Copy to clipboard", renderAction: renderCopyAction, onClick: onClick }));
50
+ };
51
+ exports.RenderQueueCopyToClipboard = RenderQueueCopyToClipboard;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RenderQueueItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const layout_1 = require("../layout");
6
+ const RenderQueueCopyToClipboard_1 = require("./RenderQueueCopyToClipboard");
6
7
  const RenderQueueError_1 = require("./RenderQueueError");
7
8
  const RenderQueueItemCancelButton_1 = require("./RenderQueueItemCancelButton");
8
9
  const RenderQueueItemStatus_1 = require("./RenderQueueItemStatus");
@@ -35,6 +36,6 @@ const subtitle = {
35
36
  overflow: 'hidden',
36
37
  };
37
38
  const RenderQueueItem = ({ job }) => {
38
- return ((0, jsx_runtime_1.jsxs)(layout_1.Row, { style: container, align: "center", children: [(0, jsx_runtime_1.jsx)(RenderQueueItemStatus_1.RenderQueueItemStatus, { job: job }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsxs)("div", { style: right, children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: job.compositionId }), (0, jsx_runtime_1.jsx)("div", { style: subtitle, children: job.status === 'done' ? ((0, jsx_runtime_1.jsx)(RenderQueueOutputName_1.RenderQueueOutputName, { job: job })) : job.status === 'failed' ? ((0, jsx_runtime_1.jsx)(RenderQueueError_1.RenderQueueError, { job: job })) : job.status === 'running' ? ((0, jsx_runtime_1.jsx)(RenderQueueProgressMessage_1.RenderQueueProgressMessage, { job: job })) : null })] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), job.status === 'done' || job.status === 'failed' ? ((0, jsx_runtime_1.jsx)(RenderQueueRepeat_1.RenderQueueRepeatItem, { job: job })) : null, job.status === 'running' ? ((0, jsx_runtime_1.jsx)(RenderQueueItemCancelButton_1.RenderQueueCancelButton, { job: job })) : ((0, jsx_runtime_1.jsx)(RenderQueueRemoveItem_1.RenderQueueRemoveItem, { job: job })), job.status === 'done' ? (0, jsx_runtime_1.jsx)(RenderQueueOpenInFolder_1.RenderQueueOpenInFinderItem, { job: job }) : null] }));
39
+ return ((0, jsx_runtime_1.jsxs)(layout_1.Row, { style: container, align: "center", children: [(0, jsx_runtime_1.jsx)(RenderQueueItemStatus_1.RenderQueueItemStatus, { job: job }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsxs)("div", { style: right, children: [(0, jsx_runtime_1.jsx)("div", { style: title, children: job.compositionId }), (0, jsx_runtime_1.jsx)("div", { style: subtitle, children: job.status === 'done' ? ((0, jsx_runtime_1.jsx)(RenderQueueOutputName_1.RenderQueueOutputName, { job: job })) : job.status === 'failed' ? ((0, jsx_runtime_1.jsx)(RenderQueueError_1.RenderQueueError, { job: job })) : job.status === 'running' ? ((0, jsx_runtime_1.jsx)(RenderQueueProgressMessage_1.RenderQueueProgressMessage, { job: job })) : null })] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, RenderQueueCopyToClipboard_1.supportsCopyingToClipboard)(job) ? ((0, jsx_runtime_1.jsx)(RenderQueueCopyToClipboard_1.RenderQueueCopyToClipboard, { job: job })) : null, job.status === 'done' || job.status === 'failed' ? ((0, jsx_runtime_1.jsx)(RenderQueueRepeat_1.RenderQueueRepeatItem, { job: job })) : null, job.status === 'running' ? ((0, jsx_runtime_1.jsx)(RenderQueueItemCancelButton_1.RenderQueueCancelButton, { job: job })) : ((0, jsx_runtime_1.jsx)(RenderQueueRemoveItem_1.RenderQueueRemoveItem, { job: job })), job.status === 'done' ? (0, jsx_runtime_1.jsx)(RenderQueueOpenInFolder_1.RenderQueueOpenInFinderItem, { job: job }) : null] }));
39
40
  };
40
41
  exports.RenderQueueItem = RenderQueueItem;
@@ -53,6 +53,9 @@ export declare const subscribeToFileExistenceWatcher: ({ file, clientId, }: {
53
53
  export declare const openInFileExplorer: ({ directory }: {
54
54
  directory: string;
55
55
  }) => Promise<void>;
56
+ export declare const copyToClipboard: ({ outName }: {
57
+ outName: string;
58
+ }) => Promise<void>;
56
59
  export declare const removeRenderJob: (job: RenderJob) => Promise<undefined>;
57
60
  export declare const cancelRenderJob: (job: RenderJob) => Promise<import("../../../preview-server/render-queue/job").CancelRenderResponse>;
58
61
  export declare const updateAvailable: (signal: AbortSignal) => Promise<import("../../../preview-server/render-queue/job").UpdateAvailableResponse>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.canUpdateDefaultProps = exports.updateDefaultProps = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addStillRenderJob = void 0;
3
+ exports.canUpdateDefaultProps = exports.updateDefaultProps = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.copyToClipboard = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addStillRenderJob = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const callApi = (endpoint, body, signal) => {
6
6
  return new Promise((resolve, reject) => {
@@ -101,6 +101,13 @@ const openInFileExplorer = ({ directory }) => {
101
101
  return callApi('/api/open-in-file-explorer', body);
102
102
  };
103
103
  exports.openInFileExplorer = openInFileExplorer;
104
+ const copyToClipboard = ({ outName }) => {
105
+ const body = {
106
+ outName,
107
+ };
108
+ return callApi('/api/copy-still-to-clipboard', body);
109
+ };
110
+ exports.copyToClipboard = copyToClipboard;
104
111
  const removeRenderJob = (job) => {
105
112
  return callApi('/api/remove-render', {
106
113
  jobId: job.id,
@@ -16,4 +16,4 @@ export declare const BLUE_DISABLED = "#284f73";
16
16
  export declare const getBackgroundFromHoverState: ({ selected, hovered, }: {
17
17
  selected: boolean;
18
18
  hovered: boolean;
19
- }) => "transparent" | "rgba(255, 255, 255, 0.06)" | "hsla(0, 0%, 100%, 0.15)" | "hsla(0, 0%, 100%, 0.25)";
19
+ }) => "transparent" | "hsla(0, 0%, 100%, 0.15)" | "hsla(0, 0%, 100%, 0.25)" | "rgba(255, 255, 255, 0.06)";
@@ -20,7 +20,7 @@ export declare const getCliOptions: (options: {
20
20
  numberOfGifLoops: import("./config/number-of-gif-loops").Loop;
21
21
  stillFrame: number;
22
22
  browserExecutable: BrowserExecutable;
23
- logLevel: "error" | "verbose" | "info" | "warn";
23
+ logLevel: "verbose" | "info" | "warn" | "error";
24
24
  scale: number;
25
25
  chromiumOptions: ChromiumOptions;
26
26
  overwrite: boolean;
@@ -33,5 +33,5 @@ export declare const getCliOptions: (options: {
33
33
  videoBitrate: string | null;
34
34
  height: number | null;
35
35
  width: number | null;
36
- configFileImageFormat: "none" | "png" | "jpeg" | undefined;
36
+ configFileImageFormat: "png" | "jpeg" | "none" | undefined;
37
37
  }>;
package/dist/index.d.ts CHANGED
@@ -63,24 +63,24 @@ export declare const CliInternals: {
63
63
  verbose: (message?: any, ...optionalParams: any[]) => void;
64
64
  verboseAdvanced: (options: {
65
65
  indent: boolean;
66
- logLevel: "error" | "verbose" | "info" | "warn";
66
+ logLevel: "verbose" | "info" | "warn" | "error";
67
67
  } & {
68
68
  tag?: string | undefined;
69
69
  }, message?: any, ...optionalParams: any[]) => void;
70
70
  info: (message?: any, ...optionalParams: any[]) => void;
71
71
  infoAdvanced: (options: {
72
72
  indent: boolean;
73
- logLevel: "error" | "verbose" | "info" | "warn";
73
+ logLevel: "verbose" | "info" | "warn" | "error";
74
74
  }, message?: any, ...optionalParams: any[]) => void;
75
75
  warn: (message?: any, ...optionalParams: any[]) => void;
76
76
  warnAdvanced: (options: {
77
77
  indent: boolean;
78
- logLevel: "error" | "verbose" | "info" | "warn";
78
+ logLevel: "verbose" | "info" | "warn" | "error";
79
79
  }, message?: any, ...optionalParams: any[]) => void;
80
80
  error: (message?: any, ...optionalParams: any[]) => void;
81
81
  errorAdvanced: (options: {
82
82
  indent: boolean;
83
- logLevel: "error" | "verbose" | "info" | "warn";
83
+ logLevel: "verbose" | "info" | "warn" | "error";
84
84
  } & {
85
85
  tag?: string | undefined;
86
86
  }, message?: any, ...optionalParams: any[]) => void;
@@ -105,7 +105,7 @@ export declare const CliInternals: {
105
105
  numberOfGifLoops: import("./config/number-of-gif-loops").Loop;
106
106
  stillFrame: number;
107
107
  browserExecutable: import("@remotion/renderer").BrowserExecutable;
108
- logLevel: "error" | "verbose" | "info" | "warn";
108
+ logLevel: "verbose" | "info" | "warn" | "error";
109
109
  scale: number;
110
110
  chromiumOptions: import("@remotion/renderer").ChromiumOptions;
111
111
  overwrite: boolean;
@@ -118,7 +118,7 @@ export declare const CliInternals: {
118
118
  videoBitrate: string | null;
119
119
  height: number | null;
120
120
  width: number | null;
121
- configFileImageFormat: "none" | "png" | "jpeg" | undefined;
121
+ configFileImageFormat: "png" | "jpeg" | "none" | undefined;
122
122
  }>;
123
123
  loadConfig: (remotionRoot: string) => Promise<string | null>;
124
124
  initializeCli: (remotionRoot: string) => Promise<void>;
@@ -127,7 +127,7 @@ export declare const CliInternals: {
127
127
  parsedCli: {
128
128
  "browser-executable": import("@remotion/renderer").BrowserExecutable;
129
129
  "pixel-format": "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
130
- "image-format": "none" | "png" | "jpeg" | "pdf" | "webp";
130
+ "image-format": "png" | "jpeg" | "pdf" | "webp" | "none";
131
131
  "prores-profile": "4444-xq" | "4444" | "hq" | "standard" | "light" | "proxy";
132
132
  "bundle-cache": string;
133
133
  "env-file": string;
@@ -180,7 +180,7 @@ export declare const CliInternals: {
180
180
  } & {
181
181
  _: string[];
182
182
  };
183
- handleCommonError: (err: Error, logLevel: "error" | "verbose" | "info" | "warn") => Promise<void>;
183
+ handleCommonError: (err: Error, logLevel: "verbose" | "info" | "warn" | "error") => Promise<void>;
184
184
  formatBytes: (number: number, options?: Intl.NumberFormatOptions & {
185
185
  locale: string;
186
186
  bits?: boolean | undefined;
@@ -192,7 +192,7 @@ export declare const CliInternals: {
192
192
  downloadName: string | null;
193
193
  outName: string | null;
194
194
  configImageFormat: "png" | "jpeg" | "pdf" | "webp" | null;
195
- cliFlag: "none" | "png" | "jpeg" | "pdf" | "webp" | null;
195
+ cliFlag: "png" | "jpeg" | "pdf" | "webp" | "none" | null;
196
196
  isLambda: boolean;
197
197
  fromUi: "png" | "jpeg" | "pdf" | "webp" | null;
198
198
  }) => {
@@ -207,8 +207,8 @@ export declare const CliInternals: {
207
207
  };
208
208
  getVideoImageFormat: ({ codec, uiImageFormat, }: {
209
209
  codec: import("@remotion/renderer").CodecOrUndefined;
210
- uiImageFormat: "none" | "png" | "jpeg" | null;
211
- }) => "none" | "png" | "jpeg";
210
+ uiImageFormat: "png" | "jpeg" | "none" | null;
211
+ }) => "png" | "jpeg" | "none";
212
212
  printCompositions: (compositions: import("remotion").VideoConfig[]) => void;
213
213
  getFinalOutputCodec: ({ cliFlag, configFile, downloadName, outName, uiCodec, }: {
214
214
  cliFlag: import("@remotion/renderer").CodecOrUndefined;
@@ -222,7 +222,7 @@ export declare const CliInternals: {
222
222
  };
223
223
  listOfRemotionPackages: string[];
224
224
  shouldUseNonOverlayingLogger: ({ logLevel, }: {
225
- logLevel: "error" | "verbose" | "info" | "warn";
225
+ logLevel: "verbose" | "info" | "warn" | "error";
226
226
  }) => boolean;
227
227
  getCompositionWithDimensionOverride: ({ height, width, args, compositionIdFromUi, chromiumOptions, envVariables, port, puppeteerInstance, timeoutInMilliseconds, browserExecutable, serveUrlOrWebpackUrl, indent, serializedInputPropsWithCustomSchema, logLevel, server, }: {
228
228
  height: number | null;
@@ -237,7 +237,7 @@ export declare const CliInternals: {
237
237
  browserExecutable: import("@remotion/renderer").BrowserExecutable;
238
238
  serveUrlOrWebpackUrl: string;
239
239
  indent: boolean;
240
- logLevel: "error" | "verbose" | "info" | "warn";
240
+ logLevel: "verbose" | "info" | "warn" | "error";
241
241
  serializedInputPropsWithCustomSchema: string;
242
242
  server: import("@remotion/renderer").RemotionServer;
243
243
  }) => Promise<{
package/dist/log.d.ts CHANGED
@@ -2,24 +2,24 @@ export declare const Log: {
2
2
  verbose: (message?: any, ...optionalParams: any[]) => void;
3
3
  verboseAdvanced: (options: {
4
4
  indent: boolean;
5
- logLevel: "error" | "verbose" | "info" | "warn";
5
+ logLevel: "verbose" | "info" | "warn" | "error";
6
6
  } & {
7
7
  tag?: string | undefined;
8
8
  }, message?: any, ...optionalParams: any[]) => void;
9
9
  info: (message?: any, ...optionalParams: any[]) => void;
10
10
  infoAdvanced: (options: {
11
11
  indent: boolean;
12
- logLevel: "error" | "verbose" | "info" | "warn";
12
+ logLevel: "verbose" | "info" | "warn" | "error";
13
13
  }, message?: any, ...optionalParams: any[]) => void;
14
14
  warn: (message?: any, ...optionalParams: any[]) => void;
15
15
  warnAdvanced: (options: {
16
16
  indent: boolean;
17
- logLevel: "error" | "verbose" | "info" | "warn";
17
+ logLevel: "verbose" | "info" | "warn" | "error";
18
18
  }, message?: any, ...optionalParams: any[]) => void;
19
19
  error: (message?: any, ...optionalParams: any[]) => void;
20
20
  errorAdvanced: (options: {
21
21
  indent: boolean;
22
- logLevel: "error" | "verbose" | "info" | "warn";
22
+ logLevel: "verbose" | "info" | "warn" | "error";
23
23
  } & {
24
24
  tag?: string | undefined;
25
25
  }, message?: any, ...optionalParams: any[]) => void;
@@ -4,6 +4,7 @@ exports.allApiRoutes = void 0;
4
4
  const add_render_1 = require("./routes/add-render");
5
5
  const can_update_default_props_1 = require("./routes/can-update-default-props");
6
6
  const cancel_render_1 = require("./routes/cancel-render");
7
+ const copy_still_to_clipboard_handler_1 = require("./routes/copy-still-to-clipboard-handler");
7
8
  const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
8
9
  const remove_render_1 = require("./routes/remove-render");
9
10
  const subscribe_to_file_existence_1 = require("./routes/subscribe-to-file-existence");
@@ -17,6 +18,7 @@ exports.allApiRoutes = {
17
18
  '/api/subscribe-to-file-existence': subscribe_to_file_existence_1.subscribeToFileExistence,
18
19
  '/api/remove-render': remove_render_1.handleRemoveRender,
19
20
  '/api/open-in-file-explorer': open_in_file_explorer_1.handleOpenInFileExplorer,
21
+ '/api/copy-still-to-clipboard': copy_still_to_clipboard_handler_1.handleCopyStillToClipboard,
20
22
  '/api/update-default-props': update_default_props_1.updateDefaultPropsHandler,
21
23
  '/api/can-update-default-props': can_update_default_props_1.canUpdateDefaultPropsHandler,
22
24
  '/api/update-available': update_available_1.handleUpdate,
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import type { IncomingMessage, ServerResponse } from 'node:http';
3
- import type { AddRenderRequest, CancelRenderRequest, CancelRenderResponse, CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse, OpenInFileExplorerRequest, RemoveRenderRequest, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, UnsubscribeFromFileExistenceRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse } from './render-queue/job';
3
+ import type { AddRenderRequest, CancelRenderRequest, CancelRenderResponse, CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse, CopyStillToClipboardRequest, OpenInFileExplorerRequest, RemoveRenderRequest, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, UnsubscribeFromFileExistenceRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse } from './render-queue/job';
4
4
  export type ApiHandler<ReqData, ResData> = (params: {
5
5
  input: ReqData;
6
6
  entryPoint: string;
@@ -19,6 +19,7 @@ export type ApiRoutes = {
19
19
  '/api/subscribe-to-file-existence': ReqAndRes<SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse>;
20
20
  '/api/remove-render': ReqAndRes<RemoveRenderRequest, undefined>;
21
21
  '/api/open-in-file-explorer': ReqAndRes<OpenInFileExplorerRequest, void>;
22
+ '/api/copy-still-to-clipboard': ReqAndRes<CopyStillToClipboardRequest, void>;
22
23
  '/api/update-default-props': ReqAndRes<UpdateDefaultPropsRequest, UpdateDefaultPropsResponse>;
23
24
  '/api/can-update-default-props': ReqAndRes<CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse>;
24
25
  '/api/update-available': ReqAndRes<UpdateAvailableRequest, UpdateAvailableResponse>;
@@ -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 | -2 | Ranges;
14
+ export declare function parseRange(size: number, str: string | string[]): -1 | Ranges | -2;
15
15
  export {};
@@ -7,14 +7,15 @@ exports.getFileSource = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const allowedFileExtensions = ['js', 'ts', 'tsx', 'jsx', 'map', 'mjs'];
10
+ // Must be async function for proper error handling
10
11
  const getFileSource = (remotionRoot, p) => {
11
12
  if (!allowedFileExtensions.find((extension) => p.endsWith(extension))) {
12
- throw new Error(`Not allowed to open ${p}`);
13
+ return Promise.reject(new Error(`Not allowed to open ${p}`));
13
14
  }
14
15
  const resolved = node_path_1.default.resolve(remotionRoot, p);
15
16
  const relativeToProcessCwd = node_path_1.default.relative(remotionRoot, resolved);
16
17
  if (relativeToProcessCwd.startsWith('..')) {
17
- throw new Error(`Not allowed to open ${relativeToProcessCwd}`);
18
+ return Promise.reject(new Error(`Not allowed to open ${relativeToProcessCwd}`));
18
19
  }
19
20
  return node_fs_1.default.promises.readFile(p, 'utf-8');
20
21
  };
@@ -0,0 +1 @@
1
+ export declare const copyStillToClipBoard: (img: string) => Promise<void>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyStillToClipBoard = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
5
+ const copyStillToClipBoard = (img) => {
6
+ return renderer_1.RenderInternals.copyImageToClipboard(img, 'info');
7
+ };
8
+ exports.copyStillToClipBoard = copyStillToClipBoard;
@@ -113,6 +113,9 @@ export type RemoveRenderRequest = {
113
113
  export type OpenInFileExplorerRequest = {
114
114
  directory: string;
115
115
  };
116
+ export type CopyStillToClipboardRequest = {
117
+ outName: string;
118
+ };
116
119
  export type SubscribeToFileExistenceRequest = {
117
120
  file: string;
118
121
  clientId: string;
@@ -0,0 +1,3 @@
1
+ import type { ApiHandler } from '../api-types';
2
+ import type { CopyStillToClipboardRequest } from '../render-queue/job';
3
+ export declare const handleCopyStillToClipboard: ApiHandler<CopyStillToClipboardRequest, void>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleCopyStillToClipboard = void 0;
7
+ const renderer_1 = require("@remotion/renderer");
8
+ const path_1 = __importDefault(require("path"));
9
+ const handleCopyStillToClipboard = ({ input: { outName }, remotionRoot }) => {
10
+ const resolved = path_1.default.resolve(remotionRoot, outName);
11
+ const relativeToProcessCwd = path_1.default.relative(remotionRoot, resolved);
12
+ if (relativeToProcessCwd.startsWith('..')) {
13
+ throw new Error(`Not allowed to open ${relativeToProcessCwd}`);
14
+ }
15
+ return renderer_1.RenderInternals.copyImageToClipboard(resolved, 'info');
16
+ };
17
+ exports.handleCopyStillToClipboard = handleCopyStillToClipboard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/cli",
3
- "version": "4.0.20",
3
+ "version": "4.0.21",
4
4
  "description": "CLI for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -35,11 +35,11 @@
35
35
  "prompts": "2.4.1",
36
36
  "semver": "7.5.3",
37
37
  "source-map": "0.6.1",
38
- "@remotion/bundler": "4.0.20",
39
- "remotion": "4.0.20",
40
- "@remotion/player": "4.0.20",
41
- "@remotion/renderer": "4.0.20",
42
- "@remotion/media-utils": "4.0.20"
38
+ "@remotion/media-utils": "4.0.21",
39
+ "@remotion/player": "4.0.21",
40
+ "@remotion/bundler": "4.0.21",
41
+ "@remotion/renderer": "4.0.21",
42
+ "remotion": "4.0.21"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": ">=16.8.0",
@@ -64,8 +64,8 @@
64
64
  "react-dom": "^18.0.0",
65
65
  "vitest": "0.31.1",
66
66
  "zod": "^3.21.4",
67
- "@remotion/tailwind": "4.0.20",
68
- "@remotion/zod-types": "4.0.20"
67
+ "@remotion/zod-types": "4.0.21",
68
+ "@remotion/tailwind": "4.0.21"
69
69
  },
70
70
  "keywords": [
71
71
  "remotion",