@remotion/renderer 4.0.501 → 4.0.503

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 (39) hide show
  1. package/dist/assets/calculate-asset-positions.d.ts +1 -1
  2. package/dist/assets/calculate-asset-positions.js +7 -1
  3. package/dist/browser/BrowserFetcher.js +61 -48
  4. package/dist/browser/browser-download-lock.d.ts +1 -0
  5. package/dist/browser/browser-download-lock.js +161 -0
  6. package/dist/client.d.ts +42 -5
  7. package/dist/client.js +6 -1
  8. package/dist/combine-chunks.d.ts +2 -2
  9. package/dist/combine-chunks.js +1 -1
  10. package/dist/create-audio.js +1 -1
  11. package/dist/esm/client.mjs +907 -692
  12. package/dist/esm/index.mjs +430 -181
  13. package/dist/esm/pure.mjs +5 -4
  14. package/dist/frame-range.d.ts +10 -1
  15. package/dist/frame-range.js +60 -36
  16. package/dist/get-duration-from-frame-range.d.ts +2 -1
  17. package/dist/get-duration-from-frame-range.js +7 -4
  18. package/dist/get-frame-to-render.d.ts +2 -1
  19. package/dist/get-frame-to-render.js +21 -5
  20. package/dist/index.d.ts +12 -3
  21. package/dist/index.js +9 -1
  22. package/dist/options/default-editor.d.ts +28 -0
  23. package/dist/options/default-editor.js +84 -0
  24. package/dist/options/frames.d.ts +4 -4
  25. package/dist/options/frames.js +51 -8
  26. package/dist/options/index.d.ts +40 -5
  27. package/dist/options/index.js +4 -0
  28. package/dist/options/rspack.d.ts +2 -2
  29. package/dist/options/rspack.js +3 -4
  30. package/dist/options/skip-skills.d.ts +19 -0
  31. package/dist/options/skip-skills.js +29 -0
  32. package/dist/pure.d.ts +1 -1
  33. package/dist/render-frame-with-option-to-reject.js +2 -1
  34. package/dist/render-frames.d.ts +5 -1
  35. package/dist/render-frames.js +42 -7
  36. package/dist/render-media.js +11 -5
  37. package/dist/validate-selected-frames.d.ts +4 -0
  38. package/dist/validate-selected-frames.js +34 -0
  39. package/package.json +13 -13
package/dist/esm/pure.mjs CHANGED
@@ -63,11 +63,12 @@ var getFramesToRender = (frameRange, everyNthFrame) => {
63
63
  if (everyNthFrame === 0) {
64
64
  throw new Error("everyNthFrame cannot be 0");
65
65
  }
66
- return new Array(frameRange[1] - frameRange[0] + 1).fill(true).map((_, index) => {
67
- return index + frameRange[0];
66
+ const ranges = Array.isArray(frameRange[0]) ? frameRange : [frameRange];
67
+ return ranges.flatMap((range) => new Array(range[1] - range[0] + 1).fill(true).map((_, index) => {
68
+ return index + range[0];
68
69
  }).filter((frame) => {
69
- return (frame - frameRange[0]) % everyNthFrame === 0;
70
- });
70
+ return (frame - range[0]) % everyNthFrame === 0;
71
+ }));
71
72
  };
72
73
 
73
74
  // src/codec.ts
@@ -1,2 +1,11 @@
1
- export type FrameRange = number | [number, number] | [number, null];
1
+ export type ResolvedFrameRange = [number, number];
2
+ export type OpenEndedFrameRange = [number, null];
3
+ export type FrameRangeTuple = ResolvedFrameRange | OpenEndedFrameRange;
4
+ export type SingleFrameRange = number | FrameRangeTuple;
5
+ export type FrameRange = SingleFrameRange | FrameRangeTuple[];
6
+ export type FrameSelection = FrameRange | {
7
+ type: 'frames';
8
+ frames: number[];
9
+ } | null;
10
+ export declare const isMultipleFrameRanges: (frameRange: FrameRange) => frameRange is FrameRangeTuple[];
2
11
  export declare const validateFrameRange: (frameRange: FrameRange | null) => void;
@@ -1,6 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateFrameRange = void 0;
3
+ exports.validateFrameRange = exports.isMultipleFrameRanges = void 0;
4
+ const isMultipleFrameRanges = (frameRange) => {
5
+ return Array.isArray(frameRange) && Array.isArray(frameRange[0]);
6
+ };
7
+ exports.isMultipleFrameRanges = isMultipleFrameRanges;
8
+ const validateFrameRangeTuple = (frameRange) => {
9
+ if (frameRange.length !== 2) {
10
+ throw new TypeError('Frame range must be a tuple, got an array with length ' +
11
+ frameRange.length);
12
+ }
13
+ const [first, second] = frameRange;
14
+ if (typeof first !== 'number') {
15
+ throw new Error(`The first value of frame range must be a number, but got ${typeof first} (${JSON.stringify(first)})`);
16
+ }
17
+ if (!Number.isFinite(first)) {
18
+ throw new TypeError('The first value of frame range must be finite, but got ' + first);
19
+ }
20
+ if (!Number.isInteger(first)) {
21
+ throw new Error(`The first value of frame range must be an integer, but got a float (${first})`);
22
+ }
23
+ if (first < 0) {
24
+ throw new Error(`The first value of frame range must be non-negative, but got ${first}`);
25
+ }
26
+ if (second === null) {
27
+ return;
28
+ }
29
+ if (typeof second !== 'number') {
30
+ throw new Error(`The second value of frame range must be a number or null, but got ${typeof second} (${JSON.stringify(second)})`);
31
+ }
32
+ if (!Number.isFinite(second)) {
33
+ throw new TypeError('The second value of frame range must be finite, but got ' + second);
34
+ }
35
+ if (!Number.isInteger(second)) {
36
+ throw new Error(`The second value of frame range must be an integer, but got a float (${second})`);
37
+ }
38
+ if (second < 0) {
39
+ throw new Error(`The second value of frame range must be non-negative, but got ${second}`);
40
+ }
41
+ if (second < first) {
42
+ throw new Error('The second value of frame range must be not smaller than the first one, but got ' +
43
+ frameRange.join('-'));
44
+ }
45
+ };
4
46
  const validateFrameRange = (frameRange) => {
5
47
  if (frameRange === null) {
6
48
  return;
@@ -17,45 +59,27 @@ const validateFrameRange = (frameRange) => {
17
59
  }
18
60
  return;
19
61
  }
20
- if (Array.isArray(frameRange)) {
21
- if (frameRange.length !== 2) {
22
- throw new TypeError('Frame range must be a tuple, got an array with length ' +
23
- frameRange.length);
24
- }
25
- const [first, second] = frameRange;
26
- if (typeof first !== 'number') {
27
- throw new Error(`The first value of frame range must be a number, but got ${typeof first} (${JSON.stringify(first)})`);
28
- }
29
- if (!Number.isFinite(first)) {
30
- throw new TypeError('The first value of frame range must be finite, but got ' + first);
31
- }
32
- if (!Number.isInteger(first)) {
33
- throw new Error(`The first value of frame range must be an integer, but got a float (${first})`);
34
- }
35
- if (first < 0) {
36
- throw new Error(`The first value of frame range must be non-negative, but got ${first}`);
37
- }
38
- if (second === null) {
39
- return;
40
- }
41
- if (typeof second !== 'number') {
42
- throw new Error(`The second value of frame range must be a number or null, but got ${typeof second} (${JSON.stringify(second)})`);
62
+ if ((0, exports.isMultipleFrameRanges)(frameRange)) {
63
+ if (frameRange.length === 0) {
64
+ throw new TypeError('Multiple frame ranges must not be empty.');
43
65
  }
44
- if (!Number.isFinite(second)) {
45
- throw new TypeError('The second value of frame range must be finite, but got ' + second);
46
- }
47
- if (!Number.isInteger(second)) {
48
- throw new Error(`The second value of frame range must be an integer, but got a float (${second})`);
49
- }
50
- if (second < 0) {
51
- throw new Error(`The second value of frame range must be non-negative, but got ${second}`);
52
- }
53
- if (second < first) {
54
- throw new Error('The second value of frame range must be not smaller than the first one, but got ' +
55
- frameRange.join('-'));
66
+ for (let index = 0; index < frameRange.length; index++) {
67
+ const range = frameRange[index];
68
+ validateFrameRangeTuple(range);
69
+ if (range[1] === null && index !== frameRange.length - 1) {
70
+ throw new Error('An open-ended frame range must be the last range.');
71
+ }
72
+ const previous = frameRange[index - 1];
73
+ if (previous && previous[1] !== null && range[0] <= previous[1]) {
74
+ throw new Error(`Frame ranges must be ordered and non-overlapping, but got ${previous.join('-')} followed by ${range.join('-')}.`);
75
+ }
56
76
  }
57
77
  return;
58
78
  }
79
+ if (Array.isArray(frameRange)) {
80
+ validateFrameRangeTuple(frameRange);
81
+ return;
82
+ }
59
83
  throw new TypeError('Frame range must be a number or a tuple of numbers, but got object of type ' +
60
84
  typeof frameRange);
61
85
  };
@@ -1 +1,2 @@
1
- export declare const getFramesToRender: (frameRange: [number, number], everyNthFrame: number) => number[];
1
+ import type { ResolvedFrameRange } from './frame-range';
2
+ export declare const getFramesToRender: (frameRange: ResolvedFrameRange[] | ResolvedFrameRange, everyNthFrame: number) => number[];
@@ -5,13 +5,16 @@ const getFramesToRender = (frameRange, everyNthFrame) => {
5
5
  if (everyNthFrame === 0) {
6
6
  throw new Error('everyNthFrame cannot be 0');
7
7
  }
8
- return new Array(frameRange[1] - frameRange[0] + 1)
8
+ const ranges = Array.isArray(frameRange[0])
9
+ ? frameRange
10
+ : [frameRange];
11
+ return ranges.flatMap((range) => new Array(range[1] - range[0] + 1)
9
12
  .fill(true)
10
13
  .map((_, index) => {
11
- return index + frameRange[0];
14
+ return index + range[0];
12
15
  })
13
16
  .filter((frame) => {
14
- return (frame - frameRange[0]) % everyNthFrame === 0;
15
- });
17
+ return (frame - range[0]) % everyNthFrame === 0;
18
+ }));
16
19
  };
17
20
  exports.getFramesToRender = getFramesToRender;
@@ -1,2 +1,3 @@
1
- import type { FrameRange } from './frame-range';
1
+ import { type FrameRange, type ResolvedFrameRange } from './frame-range';
2
+ export declare const getRealFrameRanges: (durationInFrames: number, frameRange: FrameRange | null) => ResolvedFrameRange[];
2
3
  export declare const getRealFrameRange: (durationInFrames: number, frameRange: FrameRange | null) => [number, number];
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRealFrameRange = void 0;
4
- const getRealFrameRange = (durationInFrames, frameRange) => {
5
- if (frameRange === null) {
6
- return [0, durationInFrames - 1];
7
- }
3
+ exports.getRealFrameRange = exports.getRealFrameRanges = void 0;
4
+ const frame_range_1 = require("./frame-range");
5
+ const resolveFrameRange = (durationInFrames, frameRange) => {
8
6
  if (typeof frameRange === 'number') {
9
7
  if (frameRange < 0 || frameRange >= durationInFrames) {
10
8
  throw new Error(`Frame number is out of range, must be between 0 and ${durationInFrames - 1} but got ${frameRange}`);
@@ -22,4 +20,22 @@ const getRealFrameRange = (durationInFrames, frameRange) => {
22
20
  }
23
21
  return resolved;
24
22
  };
23
+ const getRealFrameRanges = (durationInFrames, frameRange) => {
24
+ if (frameRange === null) {
25
+ return [[0, durationInFrames - 1]];
26
+ }
27
+ (0, frame_range_1.validateFrameRange)(frameRange);
28
+ if ((0, frame_range_1.isMultipleFrameRanges)(frameRange)) {
29
+ return frameRange.map((range) => resolveFrameRange(durationInFrames, range));
30
+ }
31
+ return [resolveFrameRange(durationInFrames, frameRange)];
32
+ };
33
+ exports.getRealFrameRanges = getRealFrameRanges;
34
+ const getRealFrameRange = (durationInFrames, frameRange) => {
35
+ const ranges = (0, exports.getRealFrameRanges)(durationInFrames, frameRange);
36
+ if (ranges.length !== 1) {
37
+ throw new Error('Expected a single frame range, but received multiple frame ranges.');
38
+ }
39
+ return ranges[0];
40
+ };
25
41
  exports.getRealFrameRange = getRealFrameRange;
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export { ErrorWithStackFrame } from './error-handling/handle-javascript-exceptio
18
18
  export { extractAudio } from './extract-audio';
19
19
  export type { FfmpegOverrideFn } from './ffmpeg-override';
20
20
  export { FileExtension } from './file-extensions';
21
- export { FrameRange } from './frame-range';
21
+ export { FrameRange, FrameRangeTuple, FrameSelection, OpenEndedFrameRange, ResolvedFrameRange, SingleFrameRange, } from './frame-range';
22
22
  export { GetCompositionsOptions, getCompositions, LegacyGetCompositionsOptions, } from './get-compositions';
23
23
  export { SilentPart, getSilentParts } from './get-silent-parts';
24
24
  export { VideoMetadata, getVideoMetadata } from './get-video-metadata';
@@ -31,6 +31,8 @@ export type { ChromiumOptions } from './open-browser';
31
31
  export { ChromeMode } from './options/chrome-mode';
32
32
  export { ColorSpace } from './options/color-space';
33
33
  export type { Concurrency } from './options/concurrency';
34
+ export { customEditorColumnNumberPlaceholder, customEditorLineNumberPlaceholder, customEditorTargetPathPlaceholder, defaultEditorIds, } from './options/default-editor';
35
+ export type { BuiltInEditor, CustomEditor, DefaultEditor, } from './options/default-editor';
34
36
  export type { DeleteAfter } from './options/delete-after';
35
37
  export { OpenGlRenderer } from './options/gl';
36
38
  export { NumberOfGifLoops } from './options/number-of-gif-loops';
@@ -86,6 +88,7 @@ export declare const RenderInternals: {
86
88
  isServeUrl: (potentialUrl: string) => boolean;
87
89
  ensureOutputDirectory: (outputLocation: string) => void;
88
90
  getRealFrameRange: (durationInFrames: number, frameRange: import("./frame-range").FrameRange | null) => [number, number];
91
+ getRealFrameRanges: (durationInFrames: number, frameRange: import("./frame-range").FrameRange | null) => import("./frame-range").ResolvedFrameRange[];
89
92
  validatePuppeteerTimeout: (timeoutInMilliseconds: unknown) => void;
90
93
  downloadFile: (options: {
91
94
  url: string;
@@ -108,7 +111,7 @@ export declare const RenderInternals: {
108
111
  formatStackFrameCodeFrame: (frame: import("./symbolicate-stacktrace").SymbolicatedStackFrame) => string | null;
109
112
  formatStackFrameLocationLine: (frame: import("./symbolicate-stacktrace").SymbolicatedStackFrame) => string | null;
110
113
  SymbolicateableError: typeof SymbolicateableError;
111
- getFramesToRender: (frameRange: [number, number], everyNthFrame: number) => number[];
114
+ getFramesToRender: (frameRange: import("./frame-range").ResolvedFrameRange[] | import("./frame-range").ResolvedFrameRange, everyNthFrame: number) => number[];
112
115
  getExtensionOfFilename: (filename: string | null) => string | null;
113
116
  getDesiredPort: ({ desiredPort, from, hostsToTry, to, onPortUnavailable, }: {
114
117
  desiredPort: number | undefined;
@@ -157,6 +160,10 @@ export declare const RenderInternals: {
157
160
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
158
161
  DEFAULT_BROWSER: "chrome";
159
162
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
163
+ validateSelectedFrames: ({ frames, durationInFrames, }: {
164
+ frames: unknown;
165
+ durationInFrames: number | null;
166
+ }) => number[];
160
167
  DEFAULT_OPENGL_RENDERER: "angle" | "angle-egl" | "egl" | "swangle" | "swiftshader" | "vulkan" | null;
161
168
  validateOpenGlRenderer: (option: unknown) => "angle" | "angle-egl" | "egl" | "swangle" | "swiftshader" | "vulkan" | null;
162
169
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "av1", "mp3", "aac", "wav", "prores", "h264-mkv", "h264-ts", "gif"];
@@ -1033,6 +1040,8 @@ export declare const RenderInternals: {
1033
1040
  imageFormat: "jpeg" | "none" | "png";
1034
1041
  jpegQuality: number;
1035
1042
  frameRange: import("./frame-range").FrameRange | null;
1043
+ frames: number[] | null;
1044
+ outputFramesInSequence: boolean;
1036
1045
  everyNthFrame: number;
1037
1046
  puppeteerInstance: HeadlessBrowser | undefined;
1038
1047
  browserExecutable: import("./browser-executable").BrowserExecutable;
@@ -1372,7 +1381,7 @@ export declare const RenderInternals: {
1372
1381
  audioCodec: "aac" | "mp3" | "opus" | "pcm-16" | null;
1373
1382
  cancelSignal: import("./make-cancel-signal").CancelSignal | undefined;
1374
1383
  metadata: Record<string, string> | null;
1375
- frameRange: import("./frame-range").FrameRange | null;
1384
+ frameRange: import("./frame-range").SingleFrameRange | null;
1376
1385
  everyNthFrame: number;
1377
1386
  sampleRate: number;
1378
1387
  } & {
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.RenderInternals = exports.validateOutputFilename = exports.stitchFramesToVideo = exports.selectComposition = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.openBrowser = exports.makeCancelSignal = exports.validateSelectedPixelFormatAndImageFormatCombination = exports.getVideoMetadata = exports.getSilentParts = exports.getCompositions = exports.extractAudio = exports.ErrorWithStackFrame = exports.ensureBrowser = exports.combineChunks = void 0;
39
+ exports.RenderInternals = exports.validateOutputFilename = exports.stitchFramesToVideo = exports.selectComposition = exports.renderStill = exports.renderMedia = exports.renderFrames = exports.defaultEditorIds = exports.customEditorTargetPathPlaceholder = exports.customEditorLineNumberPlaceholder = exports.customEditorColumnNumberPlaceholder = exports.openBrowser = exports.makeCancelSignal = exports.validateSelectedPixelFormatAndImageFormatCombination = exports.getVideoMetadata = exports.getSilentParts = exports.getCompositions = exports.extractAudio = exports.ErrorWithStackFrame = exports.ensureBrowser = exports.combineChunks = void 0;
40
40
  const execa_1 = __importDefault(require("execa"));
41
41
  const download_file_1 = require("./assets/download-file");
42
42
  const browser_1 = require("./browser");
@@ -88,6 +88,7 @@ const test_gpu_1 = require("./test-gpu");
88
88
  const tmp_dir_1 = require("./tmp-dir");
89
89
  const validate_concurrency_1 = require("./validate-concurrency");
90
90
  const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
91
+ const validate_selected_frames_1 = require("./validate-selected-frames");
91
92
  const combine_chunks_1 = require("./combine-chunks");
92
93
  Object.defineProperty(exports, "combineChunks", { enumerable: true, get: function () { return combine_chunks_1.combineChunks; } });
93
94
  const ensure_browser_1 = require("./ensure-browser");
@@ -108,6 +109,11 @@ const make_cancel_signal_1 = require("./make-cancel-signal");
108
109
  Object.defineProperty(exports, "makeCancelSignal", { enumerable: true, get: function () { return make_cancel_signal_1.makeCancelSignal; } });
109
110
  const open_browser_2 = require("./open-browser");
110
111
  Object.defineProperty(exports, "openBrowser", { enumerable: true, get: function () { return open_browser_2.openBrowser; } });
112
+ const default_editor_1 = require("./options/default-editor");
113
+ Object.defineProperty(exports, "customEditorColumnNumberPlaceholder", { enumerable: true, get: function () { return default_editor_1.customEditorColumnNumberPlaceholder; } });
114
+ Object.defineProperty(exports, "customEditorLineNumberPlaceholder", { enumerable: true, get: function () { return default_editor_1.customEditorLineNumberPlaceholder; } });
115
+ Object.defineProperty(exports, "customEditorTargetPathPlaceholder", { enumerable: true, get: function () { return default_editor_1.customEditorTargetPathPlaceholder; } });
116
+ Object.defineProperty(exports, "defaultEditorIds", { enumerable: true, get: function () { return default_editor_1.defaultEditorIds; } });
111
117
  const render_frames_2 = require("./render-frames");
112
118
  Object.defineProperty(exports, "renderFrames", { enumerable: true, get: function () { return render_frames_2.renderFrames; } });
113
119
  const render_media_2 = require("./render-media");
@@ -145,6 +151,7 @@ exports.RenderInternals = {
145
151
  isServeUrl: is_serve_url_1.isServeUrl,
146
152
  ensureOutputDirectory: ensure_output_directory_1.ensureOutputDirectory,
147
153
  getRealFrameRange: get_frame_to_render_1.getRealFrameRange,
154
+ getRealFrameRanges: get_frame_to_render_1.getRealFrameRanges,
148
155
  validatePuppeteerTimeout: validate_puppeteer_timeout_1.validatePuppeteerTimeout,
149
156
  downloadFile: download_file_1.downloadFile,
150
157
  parseStack: parse_browser_error_stack_1.parseStack,
@@ -167,6 +174,7 @@ exports.RenderInternals = {
167
174
  validPixelFormats: pixel_format_1.validPixelFormats,
168
175
  DEFAULT_BROWSER: browser_1.DEFAULT_BROWSER,
169
176
  validateFrameRange: frame_range_1.validateFrameRange,
177
+ validateSelectedFrames: validate_selected_frames_1.validateSelectedFrames,
170
178
  DEFAULT_OPENGL_RENDERER: gl_1.DEFAULT_OPENGL_RENDERER,
171
179
  validateOpenGlRenderer: gl_1.validateOpenGlRenderer,
172
180
  validCodecs: codec_1.validCodecs,
@@ -0,0 +1,28 @@
1
+ export declare const defaultEditorIds: readonly ["vscode", "cursor", "windsurf", "zed", "vscodium", "webstorm", "sublime-text"];
2
+ export declare const customEditorTargetPathPlaceholder: "%TARGET_PATH%";
3
+ export declare const customEditorLineNumberPlaceholder: "%LINE_NUMBER%";
4
+ export declare const customEditorColumnNumberPlaceholder: "%COLUMN_NUMBER%";
5
+ export type BuiltInEditor = (typeof defaultEditorIds)[number];
6
+ export type CustomEditor = {
7
+ readonly type: 'custom';
8
+ readonly name: string;
9
+ readonly executable: string;
10
+ readonly arguments: readonly string[];
11
+ };
12
+ export type DefaultEditor = BuiltInEditor | CustomEditor;
13
+ export declare const defaultEditorOption: {
14
+ name: string;
15
+ cliFlag: "editor";
16
+ description: () => import("react/jsx-runtime").JSX.Element;
17
+ ssrName: null;
18
+ docLink: string;
19
+ type: DefaultEditor | null;
20
+ getValue: ({ commandLine }: {
21
+ commandLine: Record<string, unknown>;
22
+ }) => {
23
+ value: DefaultEditor | null;
24
+ source: string;
25
+ };
26
+ setConfig(value: DefaultEditor | null): void;
27
+ id: "editor";
28
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultEditorOption = exports.customEditorColumnNumberPlaceholder = exports.customEditorLineNumberPlaceholder = exports.customEditorTargetPathPlaceholder = exports.defaultEditorIds = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ exports.defaultEditorIds = [
6
+ 'vscode',
7
+ 'cursor',
8
+ 'windsurf',
9
+ 'zed',
10
+ 'vscodium',
11
+ 'webstorm',
12
+ 'sublime-text',
13
+ ];
14
+ exports.customEditorTargetPathPlaceholder = '%TARGET_PATH%';
15
+ exports.customEditorLineNumberPlaceholder = '%LINE_NUMBER%';
16
+ exports.customEditorColumnNumberPlaceholder = '%COLUMN_NUMBER%';
17
+ const cliFlag = 'editor';
18
+ let defaultEditor = null;
19
+ const validateBuiltInEditor = (value, source) => {
20
+ if (typeof value !== 'string' ||
21
+ !exports.defaultEditorIds.includes(value)) {
22
+ throw new TypeError(`${source} must be one of: ${exports.defaultEditorIds.join(', ')}. Received: ${JSON.stringify(value)}`);
23
+ }
24
+ return value;
25
+ };
26
+ const validateCustomEditor = (value, source) => {
27
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
28
+ throw new TypeError(`${source} must be a built-in editor ID or a custom editor object. Received: ${JSON.stringify(value)}`);
29
+ }
30
+ const editor = value;
31
+ if (editor.type !== 'custom') {
32
+ throw new TypeError(`${source}: Custom editors must have type "custom".`);
33
+ }
34
+ if (typeof editor.name !== 'string' || editor.name.trim() === '') {
35
+ throw new TypeError(`${source}: Custom editor name must not be empty.`);
36
+ }
37
+ if (typeof editor.executable !== 'string' ||
38
+ editor.executable.trim() === '') {
39
+ throw new TypeError(`${source}: Custom editor executable must not be empty.`);
40
+ }
41
+ if (!Array.isArray(editor.arguments) ||
42
+ !editor.arguments.every((argument) => typeof argument === 'string')) {
43
+ throw new TypeError(`${source}: Custom editor arguments must be an array of strings.`);
44
+ }
45
+ if (!editor.arguments.some((argument) => argument.includes(exports.customEditorTargetPathPlaceholder))) {
46
+ throw new TypeError(`${source}: Custom editor arguments must include ${exports.customEditorTargetPathPlaceholder}.`);
47
+ }
48
+ return editor;
49
+ };
50
+ const validateDefaultEditor = (value, source) => {
51
+ if (value === null) {
52
+ return null;
53
+ }
54
+ return typeof value === 'string'
55
+ ? validateBuiltInEditor(value, source)
56
+ : validateCustomEditor(value, source);
57
+ };
58
+ exports.defaultEditorOption = {
59
+ name: 'Default editor',
60
+ cliFlag,
61
+ description: () => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: ["Set the default editor for opening files from Remotion Studio. Available editors: ",
62
+ jsx_runtime_1.jsx("code", { children: exports.defaultEditorIds.join(', ') }),
63
+ "."] })),
64
+ ssrName: null,
65
+ docLink: 'https://www.remotion.dev/docs/studio/open-in-editor',
66
+ type: null,
67
+ getValue: ({ commandLine }) => {
68
+ const cliValue = commandLine[cliFlag];
69
+ if (cliValue !== undefined && cliValue !== null) {
70
+ return {
71
+ value: validateBuiltInEditor(cliValue, `--${cliFlag}`),
72
+ source: 'cli',
73
+ };
74
+ }
75
+ return {
76
+ value: defaultEditor,
77
+ source: 'config',
78
+ };
79
+ },
80
+ setConfig(value) {
81
+ defaultEditor = validateDefaultEditor(value, 'Config.setDefaultEditor()');
82
+ },
83
+ id: cliFlag,
84
+ };
@@ -1,17 +1,17 @@
1
- import type { FrameRange } from '../frame-range';
1
+ import type { FrameSelection } from '../frame-range';
2
2
  export declare const framesOption: {
3
3
  name: string;
4
4
  cliFlag: "frames";
5
5
  description: () => import("react/jsx-runtime").JSX.Element;
6
6
  ssrName: "frameRange";
7
7
  docLink: string;
8
- type: FrameRange | null;
8
+ type: FrameSelection;
9
9
  getValue: ({ commandLine }: {
10
10
  commandLine: Record<string, unknown>;
11
11
  }) => {
12
12
  source: string;
13
- value: FrameRange | null;
13
+ value: FrameSelection;
14
14
  };
15
- setConfig: (value: FrameRange | null) => void;
15
+ setConfig: (value: FrameSelection) => void;
16
16
  id: "frames";
17
17
  };
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.framesOption = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const frame_range_1 = require("../frame-range");
6
+ const validate_selected_frames_1 = require("../validate-selected-frames");
6
7
  const cliFlag = 'frames';
7
- let frameRange = null;
8
+ let frameSelection = null;
8
9
  const parseFrameRangeFromCli = (newFrameRange) => {
9
10
  if (typeof newFrameRange === 'number') {
10
11
  if (newFrameRange < 0) {
@@ -16,6 +17,37 @@ const parseFrameRangeFromCli = (newFrameRange) => {
16
17
  if (newFrameRange.trim() === '') {
17
18
  throw new Error('--frames flag must be a single number, or 2 numbers separated by `-`');
18
19
  }
20
+ if (newFrameRange.includes(',')) {
21
+ const selectors = newFrameRange
22
+ .split(',')
23
+ .map((selector) => selector.trim());
24
+ if (selectors.some((selector) => selector === '')) {
25
+ throw new TypeError('--frames must contain a frame or frame range between commas.');
26
+ }
27
+ const onlyFrames = selectors.every((selector) => !selector.includes('-'));
28
+ if (onlyFrames) {
29
+ const frames = (0, validate_selected_frames_1.validateSelectedFrames)({
30
+ frames: selectors.map((frame) => Number(frame)),
31
+ durationInFrames: null,
32
+ });
33
+ return { type: 'frames', frames };
34
+ }
35
+ const ranges = selectors.map((selector) => {
36
+ if (!selector.includes('-')) {
37
+ const frame = Number(selector);
38
+ return [frame, frame];
39
+ }
40
+ const rangeParts = selector.split('-');
41
+ if (rangeParts.length !== 2 || rangeParts[0] === '') {
42
+ throw new Error(`Invalid frame selector "${selector}". Use a frame number, a range such as 0-9, or an open-ended range such as 100-.`);
43
+ }
44
+ const start = Number(rangeParts[0]);
45
+ const end = rangeParts[1] === '' ? null : Number(rangeParts[1]);
46
+ return [start, end];
47
+ });
48
+ (0, frame_range_1.validateFrameRange)(ranges);
49
+ return ranges;
50
+ }
19
51
  const parts = newFrameRange.split('-');
20
52
  if (parts.length > 2 || parts.length <= 0) {
21
53
  throw new Error(`--frames flag must be a number or 2 numbers separated by '-', instead got ${parts.length} numbers`);
@@ -23,7 +55,7 @@ const parseFrameRangeFromCli = (newFrameRange) => {
23
55
  if (parts.length === 1) {
24
56
  const value = Number(parts[0]);
25
57
  if (isNaN(value)) {
26
- throw new Error('--frames flag must be a single number, or 2 numbers separated by `-`');
58
+ throw new Error('--frames flag must be a frame number, range, or comma-separated selection');
27
59
  }
28
60
  return value;
29
61
  }
@@ -31,7 +63,7 @@ const parseFrameRangeFromCli = (newFrameRange) => {
31
63
  if (secondPart === '' && firstPart !== '') {
32
64
  const start = Number(firstPart);
33
65
  if (isNaN(start)) {
34
- throw new Error('--frames flag must be a single number, or 2 numbers separated by `-`');
66
+ throw new Error('--frames flag must be a frame number, range, or comma-separated selection');
35
67
  }
36
68
  return [start, null];
37
69
  }
@@ -39,7 +71,7 @@ const parseFrameRangeFromCli = (newFrameRange) => {
39
71
  const [first, second] = parsed;
40
72
  for (const value of parsed) {
41
73
  if (isNaN(value)) {
42
- throw new Error('--frames flag must be a single number, or 2 numbers separated by `-`');
74
+ throw new Error('--frames flag must be a frame number, range, or comma-separated selection');
43
75
  }
44
76
  }
45
77
  if (second < first) {
@@ -62,7 +94,15 @@ exports.framesOption = {
62
94
  getValue: ({ commandLine }) => {
63
95
  if (commandLine[cliFlag] !== undefined) {
64
96
  const value = parseFrameRangeFromCli(commandLine[cliFlag]);
65
- (0, frame_range_1.validateFrameRange)(value);
97
+ if (typeof value === 'object' && !Array.isArray(value)) {
98
+ (0, validate_selected_frames_1.validateSelectedFrames)({
99
+ frames: value.frames,
100
+ durationInFrames: null,
101
+ });
102
+ }
103
+ else {
104
+ (0, frame_range_1.validateFrameRange)(value);
105
+ }
66
106
  return {
67
107
  source: 'cli',
68
108
  value,
@@ -70,14 +110,17 @@ exports.framesOption = {
70
110
  }
71
111
  return {
72
112
  source: 'config',
73
- value: frameRange,
113
+ value: frameSelection,
74
114
  };
75
115
  },
76
116
  setConfig: (value) => {
77
- if (value !== null) {
117
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
118
+ (0, validate_selected_frames_1.validateSelectedFrames)({ frames: value.frames, durationInFrames: null });
119
+ }
120
+ else if (value !== null) {
78
121
  (0, frame_range_1.validateFrameRange)(value);
79
122
  }
80
- frameRange = value;
123
+ frameSelection = value;
81
124
  },
82
125
  id: cliFlag,
83
126
  };
@@ -1032,6 +1032,22 @@ export declare const allOptions: {
1032
1032
  setConfig: (value: boolean) => void;
1033
1033
  id: "dark-mode";
1034
1034
  };
1035
+ defaultEditorOption: {
1036
+ name: string;
1037
+ cliFlag: "editor";
1038
+ description: () => import("react/jsx-runtime").JSX.Element;
1039
+ ssrName: null;
1040
+ docLink: string;
1041
+ type: import("./default-editor").DefaultEditor | null;
1042
+ getValue: ({ commandLine }: {
1043
+ commandLine: Record<string, unknown>;
1044
+ }) => {
1045
+ value: import("./default-editor").DefaultEditor | null;
1046
+ source: string;
1047
+ };
1048
+ setConfig(value: import("./default-editor").DefaultEditor | null): void;
1049
+ id: "editor";
1050
+ };
1035
1051
  publicLicenseKeyOption: {
1036
1052
  name: string;
1037
1053
  cliFlag: "public-license-key";
@@ -1118,14 +1134,14 @@ export declare const allOptions: {
1118
1134
  description: () => import("react/jsx-runtime").JSX.Element;
1119
1135
  ssrName: "frameRange";
1120
1136
  docLink: string;
1121
- type: import("..").FrameRange | null;
1137
+ type: import("..").FrameSelection;
1122
1138
  getValue: ({ commandLine }: {
1123
1139
  commandLine: Record<string, unknown>;
1124
1140
  }) => {
1125
1141
  source: string;
1126
- value: import("..").FrameRange | null;
1142
+ value: import("..").FrameSelection;
1127
1143
  };
1128
- setConfig: (value: import("..").FrameRange | null) => void;
1144
+ setConfig: (value: import("..").FrameSelection) => void;
1129
1145
  id: "frames";
1130
1146
  };
1131
1147
  forceNewStudioOption: {
@@ -1319,7 +1335,7 @@ export declare const allOptions: {
1319
1335
  };
1320
1336
  rspackOption: {
1321
1337
  name: string;
1322
- cliFlag: "experimental-rspack";
1338
+ cliFlag: "rspack";
1323
1339
  description: () => import("react/jsx-runtime").JSX.Element;
1324
1340
  ssrName: null;
1325
1341
  docLink: null;
@@ -1331,7 +1347,7 @@ export declare const allOptions: {
1331
1347
  source: string;
1332
1348
  };
1333
1349
  setConfig(value: boolean): void;
1334
- id: "experimental-rspack";
1350
+ id: "rspack";
1335
1351
  };
1336
1352
  outDirOption: {
1337
1353
  name: string;
@@ -1371,6 +1387,25 @@ export declare const allOptions: {
1371
1387
  type: string | null;
1372
1388
  id: "package-manager";
1373
1389
  };
1390
+ skipSkillsOption: {
1391
+ name: string;
1392
+ cliFlag: "skip-skills";
1393
+ description: () => import("react/jsx-runtime").JSX.Element;
1394
+ ssrName: null;
1395
+ docLink: string;
1396
+ getValue: ({ commandLine }: {
1397
+ commandLine: Record<string, unknown>;
1398
+ }) => {
1399
+ source: string;
1400
+ value: true;
1401
+ } | {
1402
+ source: string;
1403
+ value: false;
1404
+ };
1405
+ setConfig: () => never;
1406
+ type: boolean;
1407
+ id: "skip-skills";
1408
+ };
1374
1409
  sampleRateOption: {
1375
1410
  name: string;
1376
1411
  cliFlag: "sample-rate";