@remotion/lambda 3.2.25 → 3.2.28

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.
@@ -8,16 +8,16 @@ export declare type RenderMediaOnLambdaInput = {
8
8
  functionName: string;
9
9
  serveUrl: string;
10
10
  composition: string;
11
- inputProps: unknown;
11
+ inputProps?: unknown;
12
12
  codec: LambdaCodec;
13
- imageFormat: ImageFormat;
13
+ imageFormat?: ImageFormat;
14
14
  crf?: number | undefined;
15
15
  envVariables?: Record<string, string>;
16
16
  pixelFormat?: PixelFormat;
17
17
  proResProfile?: ProResProfile;
18
- privacy: Privacy;
18
+ privacy?: Privacy;
19
19
  quality?: number;
20
- maxRetries: number;
20
+ maxRetries?: number;
21
21
  framesPerLambda?: number;
22
22
  logLevel?: LogLevel;
23
23
  frameRange?: FrameRange;
@@ -45,13 +45,13 @@ export declare type RenderMediaOnLambdaOutput = {
45
45
  * @param params.composition The ID of the composition which should be rendered.
46
46
  * @param params.inputProps The input props that should be passed to the composition.
47
47
  * @param params.codec The media codec which should be used for encoding.
48
- * @param params.imageFormat In which image format the frames should be rendered.
48
+ * @param params.imageFormat In which image format the frames should be rendered. Default "jpeg"
49
49
  * @param params.crf The constant rate factor to be used during encoding.
50
50
  * @param params.envVariables Object containing environment variables to be inserted into the video environment
51
51
  * @param params.proResProfile The ProRes profile if rendering a ProRes video
52
52
  * @param params.quality JPEG quality if JPEG was selected as the image format.
53
53
  * @param params.region The AWS region in which the media should be rendered.
54
- * @param params.maxRetries How often rendering a chunk may fail before the media render gets aborted.
54
+ * @param params.maxRetries How often rendering a chunk may fail before the media render gets aborted. Default "1"
55
55
  * @param params.logLevel Level of logging that Lambda function should perform. Default "info".
56
56
  * @returns {Promise<RenderMediaOnLambdaOutput>} See documentation for detailed structure
57
57
  */
@@ -18,13 +18,13 @@ const validate_serveurl_1 = require("../shared/validate-serveurl");
18
18
  * @param params.composition The ID of the composition which should be rendered.
19
19
  * @param params.inputProps The input props that should be passed to the composition.
20
20
  * @param params.codec The media codec which should be used for encoding.
21
- * @param params.imageFormat In which image format the frames should be rendered.
21
+ * @param params.imageFormat In which image format the frames should be rendered. Default "jpeg"
22
22
  * @param params.crf The constant rate factor to be used during encoding.
23
23
  * @param params.envVariables Object containing environment variables to be inserted into the video environment
24
24
  * @param params.proResProfile The ProRes profile if rendering a ProRes video
25
25
  * @param params.quality JPEG quality if JPEG was selected as the image format.
26
26
  * @param params.region The AWS region in which the media should be rendered.
27
- * @param params.maxRetries How often rendering a chunk may fail before the media render gets aborted.
27
+ * @param params.maxRetries How often rendering a chunk may fail before the media render gets aborted. Default "1"
28
28
  * @param params.logLevel Level of logging that Lambda function should perform. Default "info".
29
29
  * @returns {Promise<RenderMediaOnLambdaOutput>} See documentation for detailed structure
30
30
  */
@@ -46,16 +46,16 @@ const renderMediaOnLambda = async ({ functionName, serveUrl, inputProps, codec,
46
46
  framesPerLambda: framesPerLambda !== null && framesPerLambda !== void 0 ? framesPerLambda : null,
47
47
  composition,
48
48
  serveUrl: realServeUrl,
49
- inputProps,
49
+ inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
50
50
  codec: actualCodec,
51
- imageFormat,
51
+ imageFormat: imageFormat !== null && imageFormat !== void 0 ? imageFormat : 'jpeg',
52
52
  crf,
53
53
  envVariables,
54
54
  pixelFormat,
55
55
  proResProfile,
56
56
  quality,
57
- maxRetries,
58
- privacy,
57
+ maxRetries: maxRetries !== null && maxRetries !== void 0 ? maxRetries : 1,
58
+ privacy: privacy !== null && privacy !== void 0 ? privacy : 'public',
59
59
  logLevel: logLevel !== null && logLevel !== void 0 ? logLevel : 'info',
60
60
  frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
61
61
  outName: outName !== null && outName !== void 0 ? outName : null,
@@ -36,10 +36,16 @@ const renderCommand = async (args) => {
36
36
  log_1.Log.info(`${constants_1.BINARY_NAME} ${exports.RENDER_COMMAND} <serve-url> <composition-id> [output-location]`);
37
37
  (0, quit_1.quit)(1);
38
38
  }
39
- const outName = (_a = args[2]) !== null && _a !== void 0 ? _a : null;
40
- const { chromiumOptions, codec, crf, envVariables, frameRange, imageFormat, inputProps, logLevel, pixelFormat, proResProfile, puppeteerTimeout, quality, scale, everyNthFrame, numberOfGifLoops, muted, overwrite, } = await cli_1.CliInternals.getCliOptions({
39
+ const outName = args_1.parsedLambdaCli['out-name'];
40
+ const downloadName = (_a = args[2]) !== null && _a !== void 0 ? _a : null;
41
+ const { codec, reason } = cli_1.CliInternals.getFinalCodec({
42
+ downloadName,
43
+ outName: outName !== null && outName !== void 0 ? outName : null,
44
+ });
45
+ const { chromiumOptions, crf, envVariables, frameRange, imageFormat, inputProps, logLevel, pixelFormat, proResProfile, puppeteerTimeout, quality, scale, everyNthFrame, numberOfGifLoops, muted, overwrite, } = await cli_1.CliInternals.getCliOptions({
41
46
  type: 'series',
42
47
  isLambda: true,
48
+ codec,
43
49
  });
44
50
  const functionName = await (0, find_function_name_1.findFunctionName)();
45
51
  const region = (0, get_aws_region_1.getAwsRegion)();
@@ -77,9 +83,10 @@ const renderCommand = async (args) => {
77
83
  muted,
78
84
  overwrite,
79
85
  });
80
- const totalSteps = outName ? 5 : 4;
86
+ const totalSteps = downloadName ? 5 : 4;
81
87
  const progressBar = cli_1.CliInternals.createOverwriteableCliOutput(cli_1.CliInternals.quietFlagProvided());
82
- log_1.Log.info(cli_1.CliInternals.chalk.gray(`Bucket = ${res.bucketName}, renderId = ${res.renderId}, functionName = ${functionName}`));
88
+ log_1.Log.info(cli_1.CliInternals.chalk.gray(`bucket = ${res.bucketName}, function = ${functionName}`));
89
+ log_1.Log.info(cli_1.CliInternals.chalk.gray(`renderId = ${res.renderId}, codec = ${codec} (${reason})`));
83
90
  log_1.Log.verbose(`CloudWatch logs (if enabled): ${res.cloudWatchLogs}`);
84
91
  const status = await (0, get_render_progress_1.getRenderProgress)({
85
92
  functionName,
@@ -117,11 +124,11 @@ const renderCommand = async (args) => {
117
124
  downloadInfo: null,
118
125
  retriesInfo: newStatus.retriesInfo,
119
126
  }));
120
- if (outName) {
127
+ if (downloadName) {
121
128
  const downloadStart = Date.now();
122
129
  const { outputPath, sizeInBytes } = await (0, download_media_1.downloadMedia)({
123
130
  bucketName: res.bucketName,
124
- outPath: outName,
131
+ outPath: downloadName,
125
132
  region: (0, get_aws_region_1.getAwsRegion)(),
126
133
  renderId: res.renderId,
127
134
  onProgress: ({ downloaded, totalSize }) => {
@@ -15,7 +15,7 @@ const quit_1 = require("../helpers/quit");
15
15
  const log_1 = require("../log");
16
16
  exports.STILL_COMMAND = 'still';
17
17
  const stillCommand = async (args) => {
18
- var _a, _b, _c, _d;
18
+ var _a, _b, _c, _d, _e, _f;
19
19
  const serveUrl = args[0];
20
20
  if (!serveUrl) {
21
21
  log_1.Log.error('No serve URL passed.');
@@ -32,22 +32,32 @@ const stillCommand = async (args) => {
32
32
  log_1.Log.info(`${constants_1.BINARY_NAME} ${exports.STILL_COMMAND} <serve-url> <composition-id> [output-location]`);
33
33
  (0, quit_1.quit)(1);
34
34
  }
35
- const outName = (_a = args[2]) !== null && _a !== void 0 ? _a : null;
36
- const { chromiumOptions, envVariables, imageFormat, inputProps, logLevel, puppeteerTimeout, quality, stillFrame, scale, } = await cli_1.CliInternals.getCliOptions({
35
+ const downloadName = (_a = args[2]) !== null && _a !== void 0 ? _a : null;
36
+ const outName = args_1.parsedLambdaCli['out-name'];
37
+ const { chromiumOptions, envVariables, inputProps, logLevel, puppeteerTimeout, quality, stillFrame, scale, } = await cli_1.CliInternals.getCliOptions({
37
38
  type: 'still',
38
39
  isLambda: true,
40
+ codec: 'h264',
39
41
  });
40
42
  const functionName = await (0, find_function_name_1.findFunctionName)();
41
43
  const maxRetries = (_b = args_1.parsedLambdaCli['max-retries']) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_MAX_RETRIES;
42
44
  (0, validate_retries_1.validateMaxRetries)(maxRetries);
43
45
  const privacy = (_c = args_1.parsedLambdaCli.privacy) !== null && _c !== void 0 ? _c : constants_1.DEFAULT_OUTPUT_PRIVACY;
44
46
  (0, validate_privacy_1.validatePrivacy)(privacy);
47
+ const { format: imageFormat, source: imageFormatReason } = cli_1.CliInternals.determineFinalImageFormat({
48
+ downloadName,
49
+ outName: outName !== null && outName !== void 0 ? outName : null,
50
+ configImageFormat: (_d = cli_1.ConfigInternals.getUserPreferredImageFormat()) !== null && _d !== void 0 ? _d : null,
51
+ cliFlag: (_e = cli_1.CliInternals.parsedCli['image-format']) !== null && _e !== void 0 ? _e : null,
52
+ isLambda: true,
53
+ });
45
54
  try {
55
+ log_1.Log.info(cli_1.CliInternals.chalk.gray(`functionName = ${functionName}, imageFormat = ${imageFormat} (${imageFormatReason})`));
46
56
  const res = await (0, render_still_on_lambda_1.renderStillOnLambda)({
47
57
  functionName,
48
58
  serveUrl,
49
59
  inputProps,
50
- imageFormat: imageFormat,
60
+ imageFormat,
51
61
  composition,
52
62
  privacy,
53
63
  region: (0, get_aws_region_1.getAwsRegion)(),
@@ -56,18 +66,18 @@ const stillCommand = async (args) => {
56
66
  frame: stillFrame,
57
67
  quality,
58
68
  logLevel,
59
- outName: args_1.parsedLambdaCli['out-name'],
69
+ outName,
60
70
  chromiumOptions,
61
71
  timeoutInMilliseconds: puppeteerTimeout,
62
72
  scale,
63
73
  });
64
- log_1.Log.verbose(cli_1.CliInternals.chalk.gray(`Bucket = ${res.bucketName}, renderId = ${res.renderId}, functionName = ${functionName}`));
74
+ log_1.Log.info(cli_1.CliInternals.chalk.gray(`Bucket = ${res.bucketName}, renderId = ${res.renderId}`));
65
75
  log_1.Log.verbose(`CloudWatch logs (if enabled): ${res.cloudWatchLogs}`);
66
- if (outName) {
76
+ if (downloadName) {
67
77
  log_1.Log.info('Finished rendering. Downloading...');
68
78
  const { outputPath, sizeInBytes } = await (0, download_media_1.downloadMedia)({
69
79
  bucketName: res.bucketName,
70
- outPath: outName,
80
+ outPath: downloadName,
71
81
  region: (0, get_aws_region_1.getAwsRegion)(),
72
82
  renderId: res.renderId,
73
83
  });
@@ -80,7 +90,7 @@ const stillCommand = async (args) => {
80
90
  }
81
91
  }
82
92
  catch (err) {
83
- const frames = renderer_1.RenderInternals.parseStack(((_d = err.stack) !== null && _d !== void 0 ? _d : '').split('\n'));
93
+ const frames = renderer_1.RenderInternals.parseStack(((_f = err.stack) !== null && _f !== void 0 ? _f : '').split('\n'));
84
94
  const errorWithStackFrame = new renderer_1.RenderInternals.SymbolicateableError({
85
95
  message: err.message,
86
96
  frame: null,
@@ -0,0 +1,10 @@
1
+ import type { ImageFormat, StillImageFormat } from '@remotion/renderer';
2
+ export declare const getImageFormat: ({ downloadName, outName, configImageFormat, cliFlag, }: {
3
+ downloadName: string | null;
4
+ outName: string | null;
5
+ configImageFormat: ImageFormat | null;
6
+ cliFlag: ImageFormat | null;
7
+ }) => {
8
+ format: StillImageFormat;
9
+ source: string;
10
+ };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getImageFormat = void 0;
4
+ const deriveExtensionFromFilename = (filename) => {
5
+ if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.png')) {
6
+ return 'png';
7
+ }
8
+ if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.jpg')) {
9
+ return 'jpeg';
10
+ }
11
+ if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.jpeg')) {
12
+ return 'jpeg';
13
+ }
14
+ return null;
15
+ };
16
+ const getImageFormat = ({ downloadName, outName, configImageFormat, cliFlag, }) => {
17
+ const outNameExtension = deriveExtensionFromFilename(outName);
18
+ const downloadNameExtension = deriveExtensionFromFilename(downloadName);
19
+ if (outNameExtension &&
20
+ downloadNameExtension &&
21
+ outNameExtension !== downloadNameExtension) {
22
+ throw new TypeError(`Image format mismatch: ${outName} was given as the S3 output name and ${downloadName} was given as the download name, but the extensions don't match.`);
23
+ }
24
+ if (downloadNameExtension) {
25
+ if (cliFlag && downloadNameExtension !== cliFlag) {
26
+ throw new TypeError(`Image format mismatch: ${downloadName} was given as the download name, but --image-format=${cliFlag} was passed. The image formats must match.`);
27
+ }
28
+ return { format: downloadNameExtension, source: 'Download name extension' };
29
+ }
30
+ if (outNameExtension) {
31
+ if (cliFlag && outNameExtension !== cliFlag) {
32
+ throw new TypeError(`Image format mismatch: ${outName} was given as the S3 out name, but --image-format=${cliFlag} was passed. The image formats must match.`);
33
+ }
34
+ return { format: outNameExtension, source: 'Out name extension' };
35
+ }
36
+ if (cliFlag === 'none') {
37
+ throw new TypeError('The --image-format flag must not be "none" for stills.');
38
+ }
39
+ if (cliFlag !== null) {
40
+ return { format: cliFlag, source: '--image-format flag' };
41
+ }
42
+ if (configImageFormat !== null && configImageFormat !== 'none') {
43
+ return { format: configImageFormat, source: 'Config file' };
44
+ }
45
+ return { format: 'png', source: 'Default' };
46
+ };
47
+ exports.getImageFormat = getImageFormat;
@@ -0,0 +1,8 @@
1
+ import type { AwsRegion } from '../../client';
2
+ import type { LambdaRoutines } from '../../shared/constants';
3
+ export declare const getCloudwatchStreamUrl: ({ region, functionName, method, renderId, }: {
4
+ region: AwsRegion;
5
+ functionName: string;
6
+ method: LambdaRoutines;
7
+ renderId: string;
8
+ }) => string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCloudwatchStreamUrl = void 0;
4
+ const getCloudwatchStreamUrl = ({ region, functionName, method, renderId, }) => {
5
+ return `https://${region}.console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/$252Faws$252Flambda$252F${functionName}/log-events$3FfilterPattern$3D$2522method$253D${method}$252CrenderId$253D${renderId}$2522`;
6
+ };
7
+ exports.getCloudwatchStreamUrl = getCloudwatchStreamUrl;
package/dist/cli/index.js CHANGED
@@ -133,7 +133,7 @@ AWS returned an "TooManyRequestsException" error message which could mean you re
133
133
  };
134
134
  exports.executeCommand = executeCommand;
135
135
  const cli = async () => {
136
- await cli_1.CliInternals.initializeRenderCli(cli_1.CliInternals.findRemotionRoot(), 'lambda');
136
+ await cli_1.CliInternals.initializeCli(cli_1.CliInternals.findRemotionRoot());
137
137
  await (0, exports.executeCommand)(args_1.parsedLambdaCli._);
138
138
  };
139
139
  exports.cli = cli;
@@ -108,7 +108,7 @@ const innerLaunchHandler = async (params, options) => {
108
108
  if (chunkCount > constants_1.MAX_FUNCTIONS_PER_RENDER) {
109
109
  throw new Error(`Too many functions: This render would cause ${chunkCount} functions to spawn. We limit this amount to ${constants_1.MAX_FUNCTIONS_PER_RENDER} functions as more would result in diminishing returns. Values set: frameCount = ${frameCount}, framesPerLambda=${framesPerLambda}. See ${docs_url_1.DOCS_URL}/docs/lambda/concurrency for how this parameter is calculated.`);
110
110
  }
111
- (0, validate_outname_1.validateOutname)(params.outName);
111
+ (0, validate_outname_1.validateOutname)(params.outName, params.codec);
112
112
  (0, validate_privacy_1.validatePrivacy)(params.privacy);
113
113
  renderer_1.RenderInternals.validatePuppeteerTimeout(params.timeoutInMilliseconds);
114
114
  const { chunks, didUseOptimization } = (0, plan_frame_ranges_1.planFrameRanges)({
@@ -418,6 +418,9 @@ const launchHandler = async (params, options) => {
418
418
  await innerLaunchHandler(params, options);
419
419
  }
420
420
  catch (err) {
421
+ if (process.env.NODE_ENV === 'test') {
422
+ throw err;
423
+ }
421
424
  console.log('Error occurred', err);
422
425
  await (0, write_lambda_error_1.writeLambdaError)({
423
426
  bucketName: params.bucketName,
@@ -187,6 +187,9 @@ const rendererHandler = async (params, options) => {
187
187
  await renderHandler(params, options, logs);
188
188
  }
189
189
  catch (err) {
190
+ if (process.env.NODE_ENV === 'test') {
191
+ throw err;
192
+ }
190
193
  // If this error is encountered, we can just retry as it
191
194
  // is a very rare error to occur
192
195
  const isBrowserError = err.message.includes('FATAL:zygote_communication_linux.cc') ||
@@ -101,7 +101,10 @@ const innerStillHandler = async (lambdaParams, renderId, options) => {
101
101
  serveUrl: lambdaParams.serveUrl,
102
102
  dumpBrowserLogs: false,
103
103
  envVariables: lambdaParams.envVariables,
104
- frame: lambdaParams.frame,
104
+ frame: renderer_1.RenderInternals.convertToPositiveFrameIndex({
105
+ frame: lambdaParams.frame,
106
+ durationInFrames: composition.durationInFrames,
107
+ }),
105
108
  imageFormat: lambdaParams.imageFormat,
106
109
  inputProps: lambdaParams.inputProps,
107
110
  overwrite: false,
@@ -0,0 +1,23 @@
1
+ import http from 'http';
2
+ import https from 'https';
3
+ /**
4
+ * @description Calculates cryptographically secure signature for webhooks using Hmac.
5
+ * @link https://remotion.dev/docs/lambda/validate-webhooks
6
+ * @param payload Stringified request body to encode in the signature.
7
+ */
8
+ export declare function calculateSignature(payload: string): string;
9
+ export declare type InvokeWebhookInput = {
10
+ url: string;
11
+ type: 'success' | 'error' | 'timeout';
12
+ renderId: string;
13
+ };
14
+ export declare const mockableHttpClients: {
15
+ http: typeof http.request;
16
+ https: typeof https.request;
17
+ };
18
+ /**
19
+ * @description Calls a webhook.
20
+ * @link https://remotion.dev/docs/lambda/rendermediaonlambda#webhook
21
+ * @param params.url URL of webhook to call.
22
+ */
23
+ export declare function invokeWebhook({ url, type, renderId }: InvokeWebhookInput): Promise<void>;
@@ -0,0 +1,88 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.invokeWebhook = exports.mockableHttpClients = exports.calculateSignature = void 0;
30
+ const Crypto = __importStar(require("crypto"));
31
+ const http_1 = __importDefault(require("http"));
32
+ const https_1 = __importDefault(require("https"));
33
+ /**
34
+ * @description Calculates cryptographically secure signature for webhooks using Hmac.
35
+ * @link https://remotion.dev/docs/lambda/validate-webhooks
36
+ * @param payload Stringified request body to encode in the signature.
37
+ */
38
+ function calculateSignature(payload) {
39
+ const secret = 'INSECURE_DEFAULT_SECRET';
40
+ const hmac = Crypto.createHmac('sha1', secret);
41
+ const signature = 'sha1=' + hmac.update(payload).digest('hex');
42
+ return signature;
43
+ }
44
+ exports.calculateSignature = calculateSignature;
45
+ const getWebhookClient = (url) => {
46
+ if (url.startsWith('https://')) {
47
+ return exports.mockableHttpClients.https;
48
+ }
49
+ if (url.startsWith('http://')) {
50
+ return exports.mockableHttpClients.http;
51
+ }
52
+ throw new Error('Can only request URLs starting with http:// or https://');
53
+ };
54
+ exports.mockableHttpClients = {
55
+ http: http_1.default.request,
56
+ https: https_1.default.request,
57
+ };
58
+ /**
59
+ * @description Calls a webhook.
60
+ * @link https://remotion.dev/docs/lambda/rendermediaonlambda#webhook
61
+ * @param params.url URL of webhook to call.
62
+ */
63
+ function invokeWebhook({ url, type, renderId }) {
64
+ const payload = JSON.stringify({ result: type, renderId });
65
+ return new Promise((resolve, reject) => {
66
+ const req = getWebhookClient(url)(url, {
67
+ method: 'POST',
68
+ headers: {
69
+ 'Content-Type': 'application/json',
70
+ 'X-Remotion-Signature': calculateSignature(payload),
71
+ 'X-Remotion-Status': type,
72
+ },
73
+ timeout: 5000,
74
+ }, (res) => {
75
+ if (res.statusCode && res.statusCode > 299) {
76
+ reject(new Error(`Sent a webhook but got a status code of ${res.statusCode}`));
77
+ return;
78
+ }
79
+ resolve();
80
+ });
81
+ req.write(payload);
82
+ req.on('error', (err) => {
83
+ reject(err);
84
+ });
85
+ req.end();
86
+ });
87
+ }
88
+ exports.invokeWebhook = invokeWebhook;
@@ -1,2 +1,3 @@
1
+ import type { Codec } from '@remotion/renderer';
1
2
  import type { OutNameInputWithoutCredentials } from './constants';
2
- export declare const validateOutname: (outName: OutNameInputWithoutCredentials | undefined | null) => void;
3
+ export declare const validateOutname: (outName: OutNameInputWithoutCredentials | undefined | null, codec?: Codec) => void;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateOutname = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
4
5
  const validate_bucketname_1 = require("./validate-bucketname");
5
6
  const validateS3Key = (s3Key) => {
6
7
  if (typeof s3Key !== 'string') {
@@ -12,11 +13,14 @@ const validateS3Key = (s3Key) => {
12
13
  '. Check for invalid characters.');
13
14
  }
14
15
  };
15
- const validateOutname = (outName) => {
16
+ const validateOutname = (outName, codec) => {
16
17
  if (typeof outName === 'undefined' || outName === null) {
17
18
  return;
18
19
  }
19
20
  if (typeof outName === 'string') {
21
+ if (codec) {
22
+ (0, renderer_1.validateOutputFilename)(codec, renderer_1.RenderInternals.getExtensionOfFilename(outName !== null && outName !== void 0 ? outName : null));
23
+ }
20
24
  validateS3Key(outName);
21
25
  return;
22
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/lambda",
3
- "version": "3.2.25",
3
+ "version": "3.2.28",
4
4
  "description": "Distributed renderer for Remotion based on AWS Lambda",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "module": "true",
11
11
  "scripts": {
12
- "testintegration": "jest src/test/integration --runInBand",
12
+ "testintegration": "jest src/test/integration --runInBand --forceExit",
13
13
  "lint": "eslint src --ext ts,tsx",
14
14
  "test": "jest src/test/unit",
15
15
  "watch": "tsc -w",
@@ -32,12 +32,12 @@
32
32
  "@aws-sdk/client-service-quotas": "3.58.0",
33
33
  "@aws-sdk/lib-storage": "3.58.0",
34
34
  "@aws-sdk/s3-request-presigner": "3.58.0",
35
- "@remotion/bundler": "3.2.25",
36
- "@remotion/cli": "3.2.25",
37
- "@remotion/renderer": "3.2.25",
35
+ "@remotion/bundler": "3.2.28",
36
+ "@remotion/cli": "3.2.28",
37
+ "@remotion/renderer": "3.2.28",
38
38
  "aws-policies": "^1.0.1",
39
39
  "mime-types": "2.1.34",
40
- "remotion": "3.2.25"
40
+ "remotion": "3.2.28"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "react": ">=16.8.0",
@@ -62,5 +62,5 @@
62
62
  "publishConfig": {
63
63
  "access": "public"
64
64
  },
65
- "gitHead": "8e51d998e16f062336d65469cbfc9266068b7701"
65
+ "gitHead": "49bb70afa503bfb0c89ee51d8bf3386ad1b91ac4"
66
66
  }
Binary file