@remotion/lambda-client 4.0.261
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.
- package/.turbo/turbo-make.log +6 -0
- package/LICENSE.md +49 -0
- package/README.md +5 -0
- package/bundle.ts +20 -0
- package/dist/app-router-webhook.d.ts +10 -0
- package/dist/app-router-webhook.js +43 -0
- package/dist/apply-lifecycle.d.ts +8 -0
- package/dist/apply-lifecycle.js +18 -0
- package/dist/aws-clients.d.ts +11 -0
- package/dist/aws-clients.js +51 -0
- package/dist/aws-provider.d.ts +23 -0
- package/dist/aws-provider.js +94 -0
- package/dist/bucket-exists.d.ts +3 -0
- package/dist/bucket-exists.js +26 -0
- package/dist/call-lambda-async.d.ts +2 -0
- package/dist/call-lambda-async.js +20 -0
- package/dist/call-lambda-streaming.d.ts +6 -0
- package/dist/call-lambda-streaming.js +125 -0
- package/dist/call-lambda-sync.d.ts +2 -0
- package/dist/call-lambda-sync.js +30 -0
- package/dist/check-credentials.d.ts +1 -0
- package/dist/check-credentials.js +39 -0
- package/dist/clean-items.d.ts +16 -0
- package/dist/clean-items.js +25 -0
- package/dist/constants.d.ts +25 -0
- package/dist/constants.js +26 -0
- package/dist/content-disposition-header.d.ts +2 -0
- package/dist/content-disposition-header.js +50 -0
- package/dist/convert-to-serve-url.d.ts +6 -0
- package/dist/convert-to-serve-url.js +14 -0
- package/dist/create-bucket.d.ts +3 -0
- package/dist/create-bucket.js +45 -0
- package/dist/delete-file.d.ts +3 -0
- package/dist/delete-file.js +12 -0
- package/dist/delete-function.d.ts +4 -0
- package/dist/delete-function.js +15 -0
- package/dist/delete-render.d.ts +20 -0
- package/dist/delete-render.js +84 -0
- package/dist/encode-aws-url-params.d.ts +1 -0
- package/dist/encode-aws-url-params.js +7 -0
- package/dist/esm/constants.mjs +45 -0
- package/dist/esm/index.mjs +6516 -0
- package/dist/esm/regions.mjs +50 -0
- package/dist/estimate-price.d.ts +17 -0
- package/dist/estimate-price.js +45 -0
- package/dist/express-webhook.d.ts +3 -0
- package/dist/express-webhook.js +46 -0
- package/dist/get-account-id.d.ts +3 -0
- package/dist/get-account-id.js +15 -0
- package/dist/get-aws-client.d.ts +30 -0
- package/dist/get-aws-client.js +56 -0
- package/dist/get-aws-urls.d.ts +25 -0
- package/dist/get-aws-urls.js +31 -0
- package/dist/get-buckets.d.ts +9 -0
- package/dist/get-buckets.js +62 -0
- package/dist/get-compositions-on-lambda.d.ts +18 -0
- package/dist/get-compositions-on-lambda.js +59 -0
- package/dist/get-credentials.d.ts +9 -0
- package/dist/get-credentials.js +55 -0
- package/dist/get-env-variable.d.ts +1 -0
- package/dist/get-env-variable.js +15 -0
- package/dist/get-function-name.d.ts +8 -0
- package/dist/get-function-name.js +17 -0
- package/dist/get-function-version.d.ts +7 -0
- package/dist/get-function-version.js +32 -0
- package/dist/get-functions.d.ts +8 -0
- package/dist/get-functions.js +77 -0
- package/dist/get-output-url-from-metadata.d.ts +3 -0
- package/dist/get-output-url-from-metadata.js +18 -0
- package/dist/get-render-progress.d.ts +15 -0
- package/dist/get-render-progress.js +45 -0
- package/dist/get-s3-client.d.ts +9 -0
- package/dist/get-s3-client.js +14 -0
- package/dist/get-service-client.d.ts +23 -0
- package/dist/get-service-client.js +120 -0
- package/dist/get-sites.d.ts +29 -0
- package/dist/get-sites.js +79 -0
- package/dist/head-file.d.ts +3 -0
- package/dist/head-file.js +17 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.js +104 -0
- package/dist/is-cli.d.ts +2 -0
- package/dist/is-cli.js +10 -0
- package/dist/is-flaky-error.d.ts +1 -0
- package/dist/is-flaky-error.js +77 -0
- package/dist/is-in-lambda.d.ts +1 -0
- package/dist/is-in-lambda.js +9 -0
- package/dist/is-likely-to-have-aws-profile.d.ts +1 -0
- package/dist/is-likely-to-have-aws-profile.js +50 -0
- package/dist/lambda-version-string.d.ts +1 -0
- package/dist/lambda-version-string.js +7 -0
- package/dist/lifecycle-rules.d.ts +10 -0
- package/dist/lifecycle-rules.js +61 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.js +24 -0
- package/dist/list-objects.d.ts +3 -0
- package/dist/list-objects.js +67 -0
- package/dist/make-lambda-payload.d.ts +54 -0
- package/dist/make-lambda-payload.js +148 -0
- package/dist/make-s3-url.d.ts +6 -0
- package/dist/make-s3-url.js +7 -0
- package/dist/p-limit.d.ts +1 -0
- package/dist/p-limit.js +57 -0
- package/dist/pages-router-webhook.d.ts +5 -0
- package/dist/pages-router-webhook.js +48 -0
- package/dist/parse-function-name.d.ts +8 -0
- package/dist/parse-function-name.js +17 -0
- package/dist/presign-url.d.ts +14 -0
- package/dist/presign-url.js +64 -0
- package/dist/price-per-1s.d.ts +37 -0
- package/dist/price-per-1s.js +822 -0
- package/dist/random-hash.d.ts +1 -0
- package/dist/random-hash.js +13 -0
- package/dist/read-file.d.ts +9 -0
- package/dist/read-file.js +18 -0
- package/dist/regions.d.ts +3 -0
- package/dist/regions.js +48 -0
- package/dist/render-media-on-lambda.d.ts +61 -0
- package/dist/render-media-on-lambda.js +127 -0
- package/dist/render-still-on-lambda.d.ts +53 -0
- package/dist/render-still-on-lambda.js +118 -0
- package/dist/runtime-preference.d.ts +2 -0
- package/dist/runtime-preference.js +8 -0
- package/dist/speculate-function-name.d.ts +6 -0
- package/dist/speculate-function-name.js +20 -0
- package/dist/test/encode-aws-url.test.d.ts +1 -0
- package/dist/test/encode-aws-url.test.js +8 -0
- package/dist/test/price-calculation.test.d.ts +1 -0
- package/dist/test/price-calculation.test.js +61 -0
- package/dist/test/pricing.test.d.ts +1 -0
- package/dist/test/pricing.test.js +27 -0
- package/dist/test/validate-disk-size-in-mb.test.d.ts +1 -0
- package/dist/test/validate-disk-size-in-mb.test.js +14 -0
- package/dist/validate-aws-region.d.ts +2 -0
- package/dist/validate-aws-region.js +9 -0
- package/dist/validate-bucketname.d.ts +4 -0
- package/dist/validate-bucketname.js +15 -0
- package/dist/validate-disk-size-in-mb.d.ts +1 -0
- package/dist/validate-disk-size-in-mb.js +23 -0
- package/dist/validate-lambda-codec.d.ts +2 -0
- package/dist/validate-lambda-codec.js +21 -0
- package/dist/validate-memory-size.d.ts +1 -0
- package/dist/validate-memory-size.js +22 -0
- package/dist/validate-presign-expiration.d.ts +1 -0
- package/dist/validate-presign-expiration.js +29 -0
- package/dist/validate-serveurl.d.ts +1 -0
- package/dist/validate-serveurl.js +9 -0
- package/dist/validate-webhook-signature.d.ts +5 -0
- package/dist/validate-webhook-signature.js +28 -0
- package/dist/write-file.d.ts +5 -0
- package/dist/write-file.js +56 -0
- package/eslint.config.mjs +5 -0
- package/package.json +71 -0
- package/src/app-router-webhook.ts +64 -0
- package/src/apply-lifecycle.ts +30 -0
- package/src/aws-clients.ts +60 -0
- package/src/aws-provider.ts +135 -0
- package/src/bucket-exists.ts +28 -0
- package/src/call-lambda-async.ts +39 -0
- package/src/call-lambda-streaming.ts +219 -0
- package/src/call-lambda-sync.ts +55 -0
- package/src/check-credentials.ts +51 -0
- package/src/clean-items.ts +47 -0
- package/src/constants.ts +38 -0
- package/src/content-disposition-header.ts +64 -0
- package/src/convert-to-serve-url.ts +24 -0
- package/src/create-bucket.ts +67 -0
- package/src/delete-file.ts +30 -0
- package/src/delete-function.ts +24 -0
- package/src/delete-render.ts +107 -0
- package/src/encode-aws-url-params.ts +3 -0
- package/src/estimate-price.ts +95 -0
- package/src/express-webhook.ts +50 -0
- package/src/get-account-id.ts +22 -0
- package/src/get-aws-client.ts +59 -0
- package/src/get-aws-urls.ts +85 -0
- package/src/get-buckets.ts +81 -0
- package/src/get-compositions-on-lambda.ts +104 -0
- package/src/get-credentials.ts +81 -0
- package/src/get-env-variable.ts +15 -0
- package/src/get-function-name.ts +24 -0
- package/src/get-function-version.ts +43 -0
- package/src/get-functions.ts +103 -0
- package/src/get-output-url-from-metadata.ts +23 -0
- package/src/get-render-progress.ts +62 -0
- package/src/get-s3-client.ts +22 -0
- package/src/get-service-client.ts +178 -0
- package/src/get-sites.ts +128 -0
- package/src/head-file.ts +28 -0
- package/src/index.ts +147 -0
- package/src/is-cli.ts +7 -0
- package/src/is-flaky-error.ts +101 -0
- package/src/is-in-lambda.ts +5 -0
- package/src/is-likely-to-have-aws-profile.ts +55 -0
- package/src/lambda-version-string.ts +5 -0
- package/src/lifecycle-rules.ts +104 -0
- package/src/lifecycle.ts +44 -0
- package/src/list-objects.ts +83 -0
- package/src/make-lambda-payload.ts +317 -0
- package/src/make-s3-url.ts +13 -0
- package/src/p-limit.ts +75 -0
- package/src/pages-router-webhook.ts +58 -0
- package/src/parse-function-name.ts +24 -0
- package/src/presign-url.ts +110 -0
- package/src/price-per-1s.ts +863 -0
- package/src/random-hash.ts +10 -0
- package/src/read-file.ts +31 -0
- package/src/regions.ts +48 -0
- package/src/render-media-on-lambda.ts +216 -0
- package/src/render-still-on-lambda.ts +195 -0
- package/src/runtime-preference.ts +7 -0
- package/src/speculate-function-name.ts +27 -0
- package/src/test/encode-aws-url.test.ts +7 -0
- package/src/test/price-calculation.test.ts +61 -0
- package/src/test/pricing.test.ts +32 -0
- package/src/test/validate-disk-size-in-mb.test.ts +15 -0
- package/src/validate-aws-region.ts +14 -0
- package/src/validate-bucketname.ts +24 -0
- package/src/validate-disk-size-in-mb.ts +37 -0
- package/src/validate-lambda-codec.ts +28 -0
- package/src/validate-memory-size.ts +31 -0
- package/src/validate-presign-expiration.ts +46 -0
- package/src/validate-serveurl.ts +9 -0
- package/src/validate-webhook-signature.ts +42 -0
- package/src/write-file.ts +74 -0
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseBucketName = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const regions_1 = require("./regions");
|
|
6
|
+
const parseBucketName = (name) => {
|
|
7
|
+
const parsed = name.match(new RegExp(`^${constants_1.REMOTION_BUCKET_PREFIX}(.*)-([a-z0-9A-Z]+)$`));
|
|
8
|
+
const region = parsed === null || parsed === void 0 ? void 0 : parsed[1];
|
|
9
|
+
if (!region) {
|
|
10
|
+
return { region: null };
|
|
11
|
+
}
|
|
12
|
+
const realRegionFound = regions_1.AWS_REGIONS.find((r) => r.replace(/-/g, '') === region);
|
|
13
|
+
return { region: realRegionFound !== null && realRegionFound !== void 0 ? realRegionFound : null };
|
|
14
|
+
};
|
|
15
|
+
exports.parseBucketName = parseBucketName;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateDiskSizeInMb: (diskSizeInMb: unknown) => void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateDiskSizeInMb = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const validateDiskSizeInMb = (diskSizeInMb) => {
|
|
6
|
+
if (typeof diskSizeInMb !== 'number') {
|
|
7
|
+
throw new TypeError(`parameter 'diskSizeInMb' must be a number, got a ${typeof diskSizeInMb}`);
|
|
8
|
+
}
|
|
9
|
+
if (Number.isNaN(diskSizeInMb)) {
|
|
10
|
+
throw new TypeError(`parameter 'diskSizeInMb' must not be NaN, but is`);
|
|
11
|
+
}
|
|
12
|
+
if (!Number.isFinite(diskSizeInMb)) {
|
|
13
|
+
throw new TypeError(`parameter 'diskSizeInMb' must be finite, but is ${diskSizeInMb}`);
|
|
14
|
+
}
|
|
15
|
+
if (diskSizeInMb < constants_1.MIN_EPHEMERAL_STORAGE_IN_MB ||
|
|
16
|
+
diskSizeInMb > constants_1.MAX_EPHEMERAL_STORAGE_IN_MB) {
|
|
17
|
+
throw new TypeError(`parameter 'diskSizeInMb' must be between ${constants_1.MIN_EPHEMERAL_STORAGE_IN_MB} and ${constants_1.MAX_EPHEMERAL_STORAGE_IN_MB}, but got ${diskSizeInMb}`);
|
|
18
|
+
}
|
|
19
|
+
if (diskSizeInMb % 1 !== 0) {
|
|
20
|
+
throw new TypeError(`parameter 'diskSizeInMb' must be an integer but got ${diskSizeInMb}`);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
exports.validateDiskSizeInMb = validateDiskSizeInMb;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateLambdaCodec = void 0;
|
|
4
|
+
const serverless_client_1 = require("@remotion/serverless-client");
|
|
5
|
+
const validateLambdaCodec = (codec) => {
|
|
6
|
+
if (typeof codec !== 'string') {
|
|
7
|
+
throw new TypeError('"codec" must be a string ');
|
|
8
|
+
}
|
|
9
|
+
if (!serverless_client_1.serverlessCodecs.includes(codec)) {
|
|
10
|
+
throw new TypeError("'" +
|
|
11
|
+
codec +
|
|
12
|
+
"' is not a valid codec for Lambda. The following values are supported: " +
|
|
13
|
+
serverless_client_1.serverlessCodecs.join(', '));
|
|
14
|
+
}
|
|
15
|
+
if (codec === 'h264-mkv') {
|
|
16
|
+
console.warn('The "h264-mkv" codec for renderMediaOnLambda() is deprecated - it\'s now just "h264".');
|
|
17
|
+
return 'h264';
|
|
18
|
+
}
|
|
19
|
+
return codec;
|
|
20
|
+
};
|
|
21
|
+
exports.validateLambdaCodec = validateLambdaCodec;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateMemorySize: (memorySizeInMb: unknown) => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateMemorySize = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const validateMemorySize = (memorySizeInMb) => {
|
|
6
|
+
if (typeof memorySizeInMb !== 'number') {
|
|
7
|
+
throw new TypeError(`parameter 'memorySizeInMb' must be a number, got a ${typeof memorySizeInMb}`);
|
|
8
|
+
}
|
|
9
|
+
if (Number.isNaN(memorySizeInMb)) {
|
|
10
|
+
throw new TypeError(`parameter 'memorySizeInMb' must not be NaN, but is`);
|
|
11
|
+
}
|
|
12
|
+
if (!Number.isFinite(memorySizeInMb)) {
|
|
13
|
+
throw new TypeError(`parameter 'memorySizeInMb' must be finite, but is ${memorySizeInMb}`);
|
|
14
|
+
}
|
|
15
|
+
if (memorySizeInMb < constants_1.MIN_MEMORY || memorySizeInMb > constants_1.MAX_MEMORY) {
|
|
16
|
+
throw new TypeError(`parameter 'memorySizeInMb' must be between ${constants_1.MIN_MEMORY} and ${constants_1.MAX_MEMORY}, but got ${memorySizeInMb}`);
|
|
17
|
+
}
|
|
18
|
+
if (memorySizeInMb % 1 !== 0) {
|
|
19
|
+
throw new TypeError(`parameter 'memorySizeInMb' must be an integer but got ${memorySizeInMb}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.validateMemorySize = validateMemorySize;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validatePresignExpiration: (presignExpiration: unknown) => void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validatePresignExpiration = void 0;
|
|
4
|
+
const MAX_PRESIGN_EXPIRATION = 604800;
|
|
5
|
+
const MIN_PRESIGN_EXPIRATION = 1;
|
|
6
|
+
const validatePresignExpiration = (presignExpiration) => {
|
|
7
|
+
if (typeof presignExpiration === 'undefined' || presignExpiration === null) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (typeof presignExpiration !== 'number') {
|
|
11
|
+
throw new TypeError(`'expiresIn' should be a number, but is ${JSON.stringify(presignExpiration)}`);
|
|
12
|
+
}
|
|
13
|
+
if (Number.isNaN(presignExpiration)) {
|
|
14
|
+
throw new TypeError(`'expiresIn' should not be NaN, but is NaN`);
|
|
15
|
+
}
|
|
16
|
+
if (!Number.isFinite(presignExpiration)) {
|
|
17
|
+
throw new TypeError(`'expiresIn' should be finite but is ${presignExpiration}`);
|
|
18
|
+
}
|
|
19
|
+
if (presignExpiration % 1 !== 0) {
|
|
20
|
+
throw new TypeError(`'expiresIn' should be an integer but is ${JSON.stringify(presignExpiration)}`);
|
|
21
|
+
}
|
|
22
|
+
if (presignExpiration > MAX_PRESIGN_EXPIRATION) {
|
|
23
|
+
throw new TypeError(`The 'expiresIn' parameter must be less or equal than ${MAX_PRESIGN_EXPIRATION} (7 days) as enforced by AWS`);
|
|
24
|
+
}
|
|
25
|
+
if (presignExpiration < MIN_PRESIGN_EXPIRATION) {
|
|
26
|
+
throw new TypeError(`The 'expiresIn' parameter must be greater or equal than ${MIN_PRESIGN_EXPIRATION}`);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.validatePresignExpiration = validatePresignExpiration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateServeUrl: (serveUrl: unknown) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateServeUrl = void 0;
|
|
4
|
+
const validateServeUrl = (serveUrl) => {
|
|
5
|
+
if (typeof serveUrl !== 'string') {
|
|
6
|
+
throw new TypeError(`"serveURL" parameter must be a string, but is ${JSON.stringify(serveUrl)}`);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
exports.validateServeUrl = validateServeUrl;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateWebhookSignature = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* @description Validates that the signature received by a webhook endpoint is authentic. If validation fails, an error is thrown.
|
|
6
|
+
* @see [Documentation](https://remotion.dev/docs/lambda/validatewebhooksignature)
|
|
7
|
+
*/
|
|
8
|
+
const validateWebhookSignature = ({ secret, body, signatureHeader, }) => {
|
|
9
|
+
if (!secret) {
|
|
10
|
+
throw new TypeError("No 'secret' was provided to validateWebhookSignature().");
|
|
11
|
+
}
|
|
12
|
+
if (!body) {
|
|
13
|
+
throw new TypeError("No 'body' was provided to validateWebhookSignature().");
|
|
14
|
+
}
|
|
15
|
+
if (typeof require === 'undefined') {
|
|
16
|
+
throw new Error('validateWebhookSignature can only be called from Node.JS');
|
|
17
|
+
}
|
|
18
|
+
const Crypto = require('crypto');
|
|
19
|
+
const hmac = Crypto.createHmac('sha512', secret);
|
|
20
|
+
const signature = `sha512=${hmac.update(JSON.stringify(body)).digest('hex')}`;
|
|
21
|
+
if (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') {
|
|
22
|
+
throw new Error('No webhook signature was provided');
|
|
23
|
+
}
|
|
24
|
+
if (signatureHeader !== signature) {
|
|
25
|
+
throw new Error('Signatures do not match');
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.validateWebhookSignature = validateWebhookSignature;
|
|
@@ -0,0 +1,56 @@
|
|
|
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.lambdaWriteFileImplementation = void 0;
|
|
7
|
+
/* eslint-disable no-console */
|
|
8
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
9
|
+
const mime_types_1 = __importDefault(require("mime-types"));
|
|
10
|
+
const content_disposition_header_1 = require("./content-disposition-header");
|
|
11
|
+
const get_s3_client_1 = require("./get-s3-client");
|
|
12
|
+
const tryLambdaWriteFile = async ({ bucketName, key, body, region, privacy, expectedBucketOwner, downloadBehavior, customCredentials, forcePathStyle, }) => {
|
|
13
|
+
await (0, get_s3_client_1.getS3Client)({
|
|
14
|
+
region,
|
|
15
|
+
customCredentials: customCredentials,
|
|
16
|
+
forcePathStyle,
|
|
17
|
+
}).send(new client_s3_1.PutObjectCommand({
|
|
18
|
+
Bucket: bucketName,
|
|
19
|
+
Key: key,
|
|
20
|
+
Body: body,
|
|
21
|
+
ACL: privacy === 'no-acl'
|
|
22
|
+
? undefined
|
|
23
|
+
: privacy === 'private'
|
|
24
|
+
? 'private'
|
|
25
|
+
: 'public-read',
|
|
26
|
+
ExpectedBucketOwner: customCredentials
|
|
27
|
+
? undefined
|
|
28
|
+
: (expectedBucketOwner !== null && expectedBucketOwner !== void 0 ? expectedBucketOwner : undefined),
|
|
29
|
+
ContentType: mime_types_1.default.lookup(key) || 'application/octet-stream',
|
|
30
|
+
ContentDisposition: (0, content_disposition_header_1.getContentDispositionHeader)(downloadBehavior),
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
33
|
+
const lambdaWriteFileImplementation = async (params) => {
|
|
34
|
+
var _a;
|
|
35
|
+
const remainingRetries = (_a = params.retries) !== null && _a !== void 0 ? _a : 2;
|
|
36
|
+
try {
|
|
37
|
+
await tryLambdaWriteFile(params);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (remainingRetries === 0) {
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
const backoff = 2 ** (2 - remainingRetries) * 2000;
|
|
44
|
+
await new Promise((resolve) => {
|
|
45
|
+
setTimeout(resolve, backoff);
|
|
46
|
+
});
|
|
47
|
+
console.warn('Failed to write file to storage:');
|
|
48
|
+
console.warn(err);
|
|
49
|
+
console.warn(`Retrying (${remainingRetries} retries remaining)...`);
|
|
50
|
+
return (0, exports.lambdaWriteFileImplementation)({
|
|
51
|
+
...params,
|
|
52
|
+
retries: remainingRetries - 1,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.lambdaWriteFileImplementation = lambdaWriteFileImplementation;
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"repository": {
|
|
3
|
+
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/lambda-client"
|
|
4
|
+
},
|
|
5
|
+
"name": "@remotion/lambda-client",
|
|
6
|
+
"version": "4.0.261",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"author": "Jonny Burger <jonny@remotion.dev>",
|
|
10
|
+
"license": "UNLICENSED",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@aws-sdk/client-cloudwatch-logs": "3.738.0",
|
|
13
|
+
"@aws-sdk/client-iam": "3.738.0",
|
|
14
|
+
"@aws-sdk/client-lambda": "3.738.0",
|
|
15
|
+
"@aws-sdk/s3-request-presigner": "3.738.0",
|
|
16
|
+
"@aws-sdk/client-s3": "3.738.0",
|
|
17
|
+
"@aws-sdk/client-service-quotas": "3.738.0",
|
|
18
|
+
"@aws-sdk/client-sts": "3.738.0",
|
|
19
|
+
"@aws-sdk/credential-providers": "3.738.0",
|
|
20
|
+
"mime-types": "2.1.34"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/express": "^5.0.0",
|
|
24
|
+
"express": "4.21.0",
|
|
25
|
+
"eslint": "9.19.0",
|
|
26
|
+
"next": "15.1.6",
|
|
27
|
+
"@types/mime-types": "2.1.1",
|
|
28
|
+
"@remotion/serverless-client": "4.0.261",
|
|
29
|
+
"@remotion/eslint-config-internal": "4.0.261"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
"./package.json": "./package.json",
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"require": "./dist/index.js",
|
|
39
|
+
"module": "./dist/esm/index.mjs",
|
|
40
|
+
"import": "./dist/esm/index.mjs"
|
|
41
|
+
},
|
|
42
|
+
"./constants": {
|
|
43
|
+
"types": "./dist/constants.d.ts",
|
|
44
|
+
"require": "./dist/constants.js",
|
|
45
|
+
"module": "./dist/esm/constants.mjs",
|
|
46
|
+
"import": "./dist/esm/constants.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./regions": {
|
|
49
|
+
"types": "./dist/regions.d.ts",
|
|
50
|
+
"require": "./dist/regions.js",
|
|
51
|
+
"module": "./dist/esm/regions.mjs",
|
|
52
|
+
"import": "./dist/esm/regions.mjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"typesVersions": {
|
|
56
|
+
">=1.0": {
|
|
57
|
+
"constants": [
|
|
58
|
+
"dist/constants.d.ts"
|
|
59
|
+
],
|
|
60
|
+
"regions": [
|
|
61
|
+
"dist/regions.d.ts"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"formatting": "prettier src --check",
|
|
67
|
+
"test": "bun test src",
|
|
68
|
+
"lint": "eslint src",
|
|
69
|
+
"make": "tsc -d && bun --env-file=../.env.bundle bundle.ts"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
WebhookErrorPayload,
|
|
3
|
+
WebhookPayload,
|
|
4
|
+
WebhookSuccessPayload,
|
|
5
|
+
WebhookTimeoutPayload,
|
|
6
|
+
} from '@remotion/serverless-client';
|
|
7
|
+
import {validateWebhookSignature} from './validate-webhook-signature';
|
|
8
|
+
|
|
9
|
+
export type NextWebhookArgs = {
|
|
10
|
+
testing?: boolean;
|
|
11
|
+
extraHeaders?: Record<string, string>;
|
|
12
|
+
secret: string;
|
|
13
|
+
onSuccess?: (payload: WebhookSuccessPayload) => void;
|
|
14
|
+
onTimeout?: (payload: WebhookTimeoutPayload) => void;
|
|
15
|
+
onError?: (payload: WebhookErrorPayload) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const appRouterWebhook = (
|
|
19
|
+
options: NextWebhookArgs,
|
|
20
|
+
): ((req: Request) => Promise<Response>) => {
|
|
21
|
+
const {testing, extraHeaders, secret, onSuccess, onTimeout, onError} =
|
|
22
|
+
options;
|
|
23
|
+
return async function (req: Request): Promise<Response> {
|
|
24
|
+
let headers = extraHeaders || {};
|
|
25
|
+
|
|
26
|
+
if (testing) {
|
|
27
|
+
const testingheaders = {
|
|
28
|
+
'Access-Control-Allow-Origin': 'https://www.remotion.dev',
|
|
29
|
+
'Access-Control-Allow-Headers':
|
|
30
|
+
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-Remotion-Status, X-Remotion-Signature, X-Remotion-Mode',
|
|
31
|
+
'Access-Control-Allow-Methods': 'OPTIONS,POST',
|
|
32
|
+
};
|
|
33
|
+
headers = {...headers, ...testingheaders};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (req.method === 'OPTIONS') {
|
|
37
|
+
// do we have any use of the OPTIONS method other than the tester on webhooks page ? if so we can add a condition here to only return this if testing mode enabled
|
|
38
|
+
return new Response(null, {
|
|
39
|
+
headers,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Parse the body properly
|
|
44
|
+
const body = await req.json();
|
|
45
|
+
|
|
46
|
+
validateWebhookSignature({
|
|
47
|
+
secret,
|
|
48
|
+
body,
|
|
49
|
+
signatureHeader: req.headers.get('X-Remotion-Signature') as string,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const payload = body as WebhookPayload;
|
|
53
|
+
|
|
54
|
+
if (payload.type === 'success' && onSuccess) {
|
|
55
|
+
onSuccess(payload);
|
|
56
|
+
} else if (payload.type === 'timeout' && onTimeout) {
|
|
57
|
+
onTimeout(payload);
|
|
58
|
+
} else if (payload.type === 'error' && onError) {
|
|
59
|
+
onError(payload);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return new Response(JSON.stringify({success: true}), {headers});
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DeleteBucketLifecycleCommandInput,
|
|
3
|
+
LifecycleRule,
|
|
4
|
+
PutBucketLifecycleConfigurationCommandInput,
|
|
5
|
+
} from '@aws-sdk/client-s3';
|
|
6
|
+
|
|
7
|
+
export const deleteLifeCycleInput = ({
|
|
8
|
+
bucketName,
|
|
9
|
+
}: {
|
|
10
|
+
bucketName: string;
|
|
11
|
+
}): DeleteBucketLifecycleCommandInput => {
|
|
12
|
+
return {
|
|
13
|
+
Bucket: bucketName,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const createLifeCycleInput = ({
|
|
18
|
+
bucketName,
|
|
19
|
+
lcRules,
|
|
20
|
+
}: {
|
|
21
|
+
bucketName: string;
|
|
22
|
+
lcRules: LifecycleRule[];
|
|
23
|
+
}): PutBucketLifecycleConfigurationCommandInput => {
|
|
24
|
+
return {
|
|
25
|
+
Bucket: bucketName,
|
|
26
|
+
LifecycleConfiguration: {
|
|
27
|
+
Rules: lcRules,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type {CloudWatchLogsClient} from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
+
import type {IAMClient} from '@aws-sdk/client-iam';
|
|
3
|
+
import type {LambdaClient} from '@aws-sdk/client-lambda';
|
|
4
|
+
import type {ServiceQuotasClient} from '@aws-sdk/client-service-quotas';
|
|
5
|
+
import type {STSClient} from '@aws-sdk/client-sts';
|
|
6
|
+
import {getServiceClient} from './get-service-client';
|
|
7
|
+
import type {AwsRegion} from './regions';
|
|
8
|
+
|
|
9
|
+
export const getCloudWatchLogsClient = (
|
|
10
|
+
region: AwsRegion,
|
|
11
|
+
): CloudWatchLogsClient => {
|
|
12
|
+
return getServiceClient({
|
|
13
|
+
region,
|
|
14
|
+
service: 'cloudwatch',
|
|
15
|
+
customCredentials: null,
|
|
16
|
+
forcePathStyle: false,
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getLambdaClient = (
|
|
21
|
+
region: AwsRegion,
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
+
_timeoutInTest?: number,
|
|
24
|
+
): LambdaClient => {
|
|
25
|
+
return getServiceClient({
|
|
26
|
+
region,
|
|
27
|
+
service: 'lambda',
|
|
28
|
+
customCredentials: null,
|
|
29
|
+
forcePathStyle: false,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const getIamClient = (region: AwsRegion): IAMClient => {
|
|
34
|
+
return getServiceClient({
|
|
35
|
+
region,
|
|
36
|
+
service: 'iam',
|
|
37
|
+
customCredentials: null,
|
|
38
|
+
forcePathStyle: false,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const getServiceQuotasClient = (
|
|
43
|
+
region: AwsRegion,
|
|
44
|
+
): ServiceQuotasClient => {
|
|
45
|
+
return getServiceClient({
|
|
46
|
+
region,
|
|
47
|
+
service: 'servicequotas',
|
|
48
|
+
customCredentials: null,
|
|
49
|
+
forcePathStyle: false,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const getStsClient = (region: AwsRegion): STSClient => {
|
|
54
|
+
return getServiceClient({
|
|
55
|
+
region,
|
|
56
|
+
service: 'sts',
|
|
57
|
+
customCredentials: null,
|
|
58
|
+
forcePathStyle: false,
|
|
59
|
+
});
|
|
60
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type {AwsRegion} from './regions';
|
|
2
|
+
|
|
3
|
+
export type AwsProvider = {
|
|
4
|
+
type: 'aws';
|
|
5
|
+
region: AwsRegion;
|
|
6
|
+
receivedArtifactType: {
|
|
7
|
+
s3Key: string;
|
|
8
|
+
s3Url: string;
|
|
9
|
+
};
|
|
10
|
+
creationFunctionOptions: {
|
|
11
|
+
createCloudWatchLogGroup: boolean;
|
|
12
|
+
accountId: string;
|
|
13
|
+
alreadyCreated: boolean;
|
|
14
|
+
retentionInDays: number;
|
|
15
|
+
customRoleArn: string;
|
|
16
|
+
enableLambdaInsights: boolean;
|
|
17
|
+
vpcSubnetIds: string;
|
|
18
|
+
vpcSecurityGroupIds: string;
|
|
19
|
+
runtimePreference: RuntimePreference;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
import type {ProviderSpecifics} from '@remotion/serverless-client';
|
|
24
|
+
import {expiryDays} from '@remotion/serverless-client';
|
|
25
|
+
import {EventEmitter} from 'node:events';
|
|
26
|
+
import {bucketExistsInRegionImplementation} from './bucket-exists';
|
|
27
|
+
import {callFunctionAsyncImplementation} from './call-lambda-async';
|
|
28
|
+
import {callFunctionWithStreamingImplementation} from './call-lambda-streaming';
|
|
29
|
+
import {callFunctionSyncImplementation} from './call-lambda-sync';
|
|
30
|
+
import {checkCredentials} from './check-credentials';
|
|
31
|
+
import {MAX_EPHEMERAL_STORAGE_IN_MB, REMOTION_BUCKET_PREFIX} from './constants';
|
|
32
|
+
import {convertToServeUrlImplementation} from './convert-to-serve-url';
|
|
33
|
+
import {createBucket} from './create-bucket';
|
|
34
|
+
import {lambdaDeleteFileImplementation} from './delete-file';
|
|
35
|
+
import {deleteFunction} from './delete-function';
|
|
36
|
+
import {estimatePrice} from './estimate-price';
|
|
37
|
+
import {getAccountIdImplementation} from './get-account-id';
|
|
38
|
+
import {getCloudwatchMethodUrl, getCloudwatchRendererUrl} from './get-aws-urls';
|
|
39
|
+
import {getRemotionBuckets} from './get-buckets';
|
|
40
|
+
import {getFunctions} from './get-functions';
|
|
41
|
+
import {getOutputUrlFromMetadata} from './get-output-url-from-metadata';
|
|
42
|
+
import {lambdaHeadFileImplementation} from './head-file';
|
|
43
|
+
import {isFlakyError} from './is-flaky-error';
|
|
44
|
+
import {applyLifeCyleOperation} from './lifecycle-rules';
|
|
45
|
+
import {lambdaLsImplementation} from './list-objects';
|
|
46
|
+
import {parseFunctionName} from './parse-function-name';
|
|
47
|
+
import {randomHashImplementation} from './random-hash';
|
|
48
|
+
import {lambdaReadFileImplementation} from './read-file';
|
|
49
|
+
import type {RuntimePreference} from './runtime-preference';
|
|
50
|
+
import {lambdaWriteFileImplementation} from './write-file';
|
|
51
|
+
|
|
52
|
+
if (
|
|
53
|
+
/^AWS_Lambda_nodejs(?:18|20)[.]x$/.test(
|
|
54
|
+
process.env.AWS_EXECUTION_ENV ?? '',
|
|
55
|
+
) === true
|
|
56
|
+
) {
|
|
57
|
+
process.env.FONTCONFIG_PATH = '/opt';
|
|
58
|
+
process.env.FONTCONFIG_FILE = '/opt/fonts.conf';
|
|
59
|
+
|
|
60
|
+
process.env.DISABLE_FROM_SURFACE = '1';
|
|
61
|
+
process.env.NO_COLOR = '1';
|
|
62
|
+
|
|
63
|
+
// @ts-expect-error
|
|
64
|
+
globalThis._dumpUnreleasedBuffers = new EventEmitter();
|
|
65
|
+
|
|
66
|
+
// @ts-expect-error
|
|
67
|
+
(globalThis._dumpUnreleasedBuffers as EventEmitter).setMaxListeners(201);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const validateDeleteAfter = (lifeCycleValue: unknown) => {
|
|
71
|
+
if (lifeCycleValue === null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (lifeCycleValue === undefined) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof lifeCycleValue !== 'string') {
|
|
80
|
+
throw new TypeError(
|
|
81
|
+
`Expected life cycle value to be a string, got ${JSON.stringify(
|
|
82
|
+
lifeCycleValue,
|
|
83
|
+
)}`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!(lifeCycleValue in expiryDays)) {
|
|
88
|
+
throw new TypeError(
|
|
89
|
+
`Expected deleteAfter value to be one of ${Object.keys(expiryDays).join(
|
|
90
|
+
', ',
|
|
91
|
+
)}, got ${lifeCycleValue}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const awsImplementation: ProviderSpecifics<AwsProvider> = {
|
|
97
|
+
getChromiumPath() {
|
|
98
|
+
return '/opt/bin/chromium';
|
|
99
|
+
},
|
|
100
|
+
getBuckets: getRemotionBuckets,
|
|
101
|
+
createBucket,
|
|
102
|
+
applyLifeCycle: applyLifeCyleOperation,
|
|
103
|
+
listObjects: lambdaLsImplementation,
|
|
104
|
+
deleteFile: lambdaDeleteFileImplementation,
|
|
105
|
+
bucketExists: bucketExistsInRegionImplementation,
|
|
106
|
+
randomHash: randomHashImplementation,
|
|
107
|
+
readFile: lambdaReadFileImplementation,
|
|
108
|
+
writeFile: lambdaWriteFileImplementation,
|
|
109
|
+
headFile: lambdaHeadFileImplementation,
|
|
110
|
+
convertToServeUrl: convertToServeUrlImplementation,
|
|
111
|
+
printLoggingHelper: true,
|
|
112
|
+
validateDeleteAfter,
|
|
113
|
+
callFunctionAsync: callFunctionAsyncImplementation,
|
|
114
|
+
callFunctionStreaming: callFunctionWithStreamingImplementation,
|
|
115
|
+
callFunctionSync: callFunctionSyncImplementation,
|
|
116
|
+
getEphemeralStorageForPriceCalculation() {
|
|
117
|
+
// We cannot determine the ephemeral storage size, so we
|
|
118
|
+
// overestimate the price, but will only have a miniscule effect (~0.2%)
|
|
119
|
+
return MAX_EPHEMERAL_STORAGE_IN_MB;
|
|
120
|
+
},
|
|
121
|
+
estimatePrice,
|
|
122
|
+
getLoggingUrlForMethod: getCloudwatchMethodUrl,
|
|
123
|
+
getLoggingUrlForRendererFunction: getCloudwatchRendererUrl,
|
|
124
|
+
isFlakyError,
|
|
125
|
+
getOutputUrl: getOutputUrlFromMetadata,
|
|
126
|
+
serverStorageProductName: () => 'S3',
|
|
127
|
+
getMaxStillInlinePayloadSize: () => 5_000_000,
|
|
128
|
+
getMaxNonInlinePayloadSizePerFunction: () => 200_000,
|
|
129
|
+
getAccountId: getAccountIdImplementation,
|
|
130
|
+
deleteFunction,
|
|
131
|
+
getFunctions,
|
|
132
|
+
parseFunctionName,
|
|
133
|
+
checkCredentials,
|
|
134
|
+
getBucketPrefix: () => REMOTION_BUCKET_PREFIX,
|
|
135
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {GetBucketLocationCommand} from '@aws-sdk/client-s3';
|
|
2
|
+
import type {ProviderSpecifics} from '@remotion/serverless-client';
|
|
3
|
+
import type {AwsProvider} from './aws-provider';
|
|
4
|
+
import {getS3Client} from './get-s3-client';
|
|
5
|
+
|
|
6
|
+
export const bucketExistsInRegionImplementation: ProviderSpecifics<AwsProvider>['bucketExists'] =
|
|
7
|
+
async ({bucketName, region, expectedBucketOwner, forcePathStyle}) => {
|
|
8
|
+
try {
|
|
9
|
+
const bucket = await getS3Client({
|
|
10
|
+
region,
|
|
11
|
+
customCredentials: null,
|
|
12
|
+
forcePathStyle,
|
|
13
|
+
}).send(
|
|
14
|
+
new GetBucketLocationCommand({
|
|
15
|
+
Bucket: bucketName,
|
|
16
|
+
ExpectedBucketOwner: expectedBucketOwner ?? undefined,
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return (bucket.LocationConstraint ?? 'us-east-1') === region;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
if ((err as {Code: string}).Code === 'NoSuchBucket') {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
};
|