@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
|
+
export const getEnvVariable = (name: string) => {
|
|
2
|
+
if (
|
|
3
|
+
typeof process !== 'undefined' &&
|
|
4
|
+
typeof process.env !== 'undefined' &&
|
|
5
|
+
process.env[name]
|
|
6
|
+
) {
|
|
7
|
+
return process.env[name];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (typeof Deno !== 'undefined' && Deno.env.has(name)) {
|
|
11
|
+
return Deno.env.get(name);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return undefined;
|
|
15
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {RENDER_FN_PREFIX} from './constants';
|
|
2
|
+
|
|
3
|
+
type ReturnType = {
|
|
4
|
+
version: string;
|
|
5
|
+
memorySizeInMb: number;
|
|
6
|
+
diskSizeInMb: number;
|
|
7
|
+
timeoutInSeconds: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const parseFunctionName = (functionName: string): ReturnType | null => {
|
|
11
|
+
const match = functionName.match(
|
|
12
|
+
new RegExp(RENDER_FN_PREFIX + '(.*)-mem(\\d+)mb-disk(\\d+)mb-(\\d+)sec$'),
|
|
13
|
+
);
|
|
14
|
+
if (!match) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
version: match[1],
|
|
20
|
+
memorySizeInMb: parseInt(match[2], 10),
|
|
21
|
+
diskSizeInMb: parseInt(match[3], 10),
|
|
22
|
+
timeoutInSeconds: parseInt(match[4], 10),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type {LogLevel} from '@remotion/serverless-client';
|
|
2
|
+
import {
|
|
3
|
+
COMMAND_NOT_FOUND,
|
|
4
|
+
ServerlessRoutines,
|
|
5
|
+
} from '@remotion/serverless-client';
|
|
6
|
+
import {awsImplementation} from './aws-provider';
|
|
7
|
+
import type {AwsRegion} from './regions';
|
|
8
|
+
|
|
9
|
+
export const getFunctionVersion = async ({
|
|
10
|
+
functionName,
|
|
11
|
+
region,
|
|
12
|
+
logLevel,
|
|
13
|
+
}: {
|
|
14
|
+
functionName: string;
|
|
15
|
+
region: AwsRegion;
|
|
16
|
+
logLevel: LogLevel;
|
|
17
|
+
}): Promise<string> => {
|
|
18
|
+
try {
|
|
19
|
+
const result = await awsImplementation.callFunctionSync({
|
|
20
|
+
functionName,
|
|
21
|
+
payload: {
|
|
22
|
+
logLevel,
|
|
23
|
+
type: ServerlessRoutines.info,
|
|
24
|
+
},
|
|
25
|
+
region,
|
|
26
|
+
type: ServerlessRoutines.info,
|
|
27
|
+
timeoutInTest: 120000,
|
|
28
|
+
});
|
|
29
|
+
return result.version;
|
|
30
|
+
} catch (err) {
|
|
31
|
+
// Prerelease versions had no info command
|
|
32
|
+
if ((err as Error).message.includes(COMMAND_NOT_FOUND)) {
|
|
33
|
+
return 'n/a';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Bug in certain version of AWS S3 kit
|
|
37
|
+
if ((err as Error).message.includes('AWS CRT binary not present ')) {
|
|
38
|
+
return 'n/a';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type {FunctionConfiguration} from '@aws-sdk/client-lambda';
|
|
2
|
+
import {ListFunctionsCommand} from '@aws-sdk/client-lambda';
|
|
3
|
+
import type {FunctionInfo, LogLevel} from '@remotion/serverless-client';
|
|
4
|
+
import {VERSION} from '@remotion/serverless-client';
|
|
5
|
+
import {getLambdaClient} from './aws-clients';
|
|
6
|
+
import {DEFAULT_EPHEMERAL_STORAGE_IN_MB, RENDER_FN_PREFIX} from './constants';
|
|
7
|
+
import {getFunctionVersion} from './get-function-version';
|
|
8
|
+
import type {AwsRegion} from './regions';
|
|
9
|
+
|
|
10
|
+
export type GetFunctionsInput = {
|
|
11
|
+
region: AwsRegion;
|
|
12
|
+
compatibleOnly: boolean;
|
|
13
|
+
logLevel?: LogLevel;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const getAllFunctions = async ({
|
|
17
|
+
existing,
|
|
18
|
+
nextMarker,
|
|
19
|
+
region,
|
|
20
|
+
}: {
|
|
21
|
+
existing: FunctionConfiguration[];
|
|
22
|
+
nextMarker: string | null;
|
|
23
|
+
region: AwsRegion;
|
|
24
|
+
}): Promise<FunctionConfiguration[]> => {
|
|
25
|
+
const allLambdas: FunctionConfiguration[] = [...existing];
|
|
26
|
+
const lambdas = await getLambdaClient(region).send(
|
|
27
|
+
new ListFunctionsCommand({
|
|
28
|
+
Marker: nextMarker ?? undefined,
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
if (!lambdas.Functions) {
|
|
32
|
+
return allLambdas;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const lambda of lambdas.Functions) {
|
|
36
|
+
allLambdas.push(lambda);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (lambdas.NextMarker) {
|
|
40
|
+
return getAllFunctions({
|
|
41
|
+
existing: allLambdas,
|
|
42
|
+
nextMarker: lambdas.NextMarker,
|
|
43
|
+
region,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return allLambdas;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* @description Retrieves a list of functions that Remotion deployed to AWS Lambda in a certain region.
|
|
52
|
+
* @see [Documentation](https://remotion.dev/docs/lambda/getfunctions)
|
|
53
|
+
*/
|
|
54
|
+
export const getFunctions = async (
|
|
55
|
+
params: GetFunctionsInput,
|
|
56
|
+
): Promise<FunctionInfo[]> => {
|
|
57
|
+
const lambdas = await getAllFunctions({
|
|
58
|
+
existing: [],
|
|
59
|
+
nextMarker: null,
|
|
60
|
+
region: params.region,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const remotionLambdas = lambdas.filter((f) => {
|
|
64
|
+
return f.FunctionName?.startsWith(RENDER_FN_PREFIX);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const configs = await Promise.all(
|
|
68
|
+
remotionLambdas.map(async (fn) => {
|
|
69
|
+
try {
|
|
70
|
+
const version = await getFunctionVersion({
|
|
71
|
+
functionName: fn.FunctionName as string,
|
|
72
|
+
region: params.region,
|
|
73
|
+
logLevel: params.logLevel ?? 'info',
|
|
74
|
+
});
|
|
75
|
+
return version;
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const list = remotionLambdas.map((lambda, i): FunctionInfo => {
|
|
83
|
+
return {
|
|
84
|
+
functionName: lambda.FunctionName as string,
|
|
85
|
+
version: configs[i],
|
|
86
|
+
memorySizeInMb: lambda.MemorySize as number,
|
|
87
|
+
timeoutInSeconds: lambda.Timeout as number,
|
|
88
|
+
diskSizeInMb:
|
|
89
|
+
lambda.EphemeralStorage?.Size ?? DEFAULT_EPHEMERAL_STORAGE_IN_MB,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
if (!params.compatibleOnly) {
|
|
93
|
+
return list;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return list.filter((l) => {
|
|
97
|
+
if (!params.compatibleOnly) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return l.version === VERSION;
|
|
102
|
+
});
|
|
103
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type {GetOutputUrl} from '@remotion/serverless-client';
|
|
2
|
+
import {getExpectedOutName} from '@remotion/serverless-client';
|
|
3
|
+
import type {AwsProvider} from './aws-provider';
|
|
4
|
+
import {REMOTION_BUCKET_PREFIX} from './constants';
|
|
5
|
+
|
|
6
|
+
export const getOutputUrlFromMetadata: GetOutputUrl<AwsProvider> = ({
|
|
7
|
+
renderMetadata,
|
|
8
|
+
bucketName,
|
|
9
|
+
customCredentials,
|
|
10
|
+
currentRegion,
|
|
11
|
+
}) => {
|
|
12
|
+
const {key, renderBucketName} = getExpectedOutName({
|
|
13
|
+
renderMetadata,
|
|
14
|
+
bucketName,
|
|
15
|
+
customCredentials,
|
|
16
|
+
bucketNamePrefix: REMOTION_BUCKET_PREFIX,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
url: `https://s3.${currentRegion}.amazonaws.com/${renderBucketName}/${key}`,
|
|
21
|
+
key,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type {CustomCredentials, LogLevel} from '@remotion/serverless-client';
|
|
2
|
+
import {getProgress, ServerlessRoutines} from '@remotion/serverless-client';
|
|
3
|
+
import {awsImplementation, type AwsProvider} from './aws-provider';
|
|
4
|
+
import type {RenderProgress} from './constants';
|
|
5
|
+
import {getRenderProgressPayload} from './make-lambda-payload';
|
|
6
|
+
import {parseFunctionName} from './parse-function-name';
|
|
7
|
+
import type {AwsRegion} from './regions';
|
|
8
|
+
|
|
9
|
+
export type GetRenderProgressInput = {
|
|
10
|
+
functionName: string;
|
|
11
|
+
bucketName: string;
|
|
12
|
+
renderId: string;
|
|
13
|
+
region: AwsRegion;
|
|
14
|
+
logLevel?: LogLevel;
|
|
15
|
+
s3OutputProvider?: CustomCredentials<AwsProvider>;
|
|
16
|
+
forcePathStyle?: boolean;
|
|
17
|
+
skipLambdaInvocation?: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* @description Gets the current status of a render originally triggered via renderMediaOnLambda().
|
|
22
|
+
* @see [Documentation](https://remotion.dev/docs/lambda/getrenderprogress)
|
|
23
|
+
*/
|
|
24
|
+
export const getRenderProgress = async (
|
|
25
|
+
input: GetRenderProgressInput,
|
|
26
|
+
): Promise<RenderProgress> => {
|
|
27
|
+
if (input.skipLambdaInvocation) {
|
|
28
|
+
const parsed = parseFunctionName(input.functionName);
|
|
29
|
+
if (!parsed) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
[
|
|
32
|
+
`The function name ${input.functionName} does not adhere to the function name convention (https://www.remotion.dev/docs/lambda/naming-convention).`,
|
|
33
|
+
'Cannot determine memory and disk size from the function name.',
|
|
34
|
+
'You must call getRenderProgress with `skipLambdaInvocation` set to false.',
|
|
35
|
+
].join('\n'),
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return getProgress<AwsProvider>({
|
|
40
|
+
bucketName: input.bucketName,
|
|
41
|
+
renderId: input.renderId,
|
|
42
|
+
region: input.region,
|
|
43
|
+
forcePathStyle: input.forcePathStyle ?? false,
|
|
44
|
+
customCredentials: input.s3OutputProvider ?? null,
|
|
45
|
+
expectedBucketOwner: null,
|
|
46
|
+
providerSpecifics: awsImplementation,
|
|
47
|
+
memorySizeInMb: parsed.memorySizeInMb,
|
|
48
|
+
timeoutInMilliseconds: parsed.timeoutInSeconds * 1000,
|
|
49
|
+
functionName: input.functionName,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const result =
|
|
54
|
+
await awsImplementation.callFunctionSync<ServerlessRoutines.status>({
|
|
55
|
+
functionName: input.functionName,
|
|
56
|
+
type: ServerlessRoutines.status,
|
|
57
|
+
payload: getRenderProgressPayload(input),
|
|
58
|
+
region: input.region,
|
|
59
|
+
timeoutInTest: 120000,
|
|
60
|
+
});
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type {S3Client} from '@aws-sdk/client-s3';
|
|
2
|
+
import type {CustomCredentials} from '@remotion/serverless-client';
|
|
3
|
+
import type {AwsProvider} from './aws-provider';
|
|
4
|
+
import {getServiceClient} from './get-service-client';
|
|
5
|
+
import type {AwsRegion} from './regions';
|
|
6
|
+
|
|
7
|
+
export const getS3Client = ({
|
|
8
|
+
region,
|
|
9
|
+
customCredentials,
|
|
10
|
+
forcePathStyle,
|
|
11
|
+
}: {
|
|
12
|
+
region: AwsRegion;
|
|
13
|
+
customCredentials: CustomCredentials<AwsProvider> | null;
|
|
14
|
+
forcePathStyle: boolean;
|
|
15
|
+
}): S3Client => {
|
|
16
|
+
return getServiceClient({
|
|
17
|
+
region: customCredentials?.region ?? region,
|
|
18
|
+
service: 's3',
|
|
19
|
+
customCredentials,
|
|
20
|
+
forcePathStyle,
|
|
21
|
+
});
|
|
22
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {CloudWatchLogsClient} from '@aws-sdk/client-cloudwatch-logs';
|
|
2
|
+
import {IAMClient} from '@aws-sdk/client-iam';
|
|
3
|
+
import {LambdaClient} from '@aws-sdk/client-lambda';
|
|
4
|
+
import {S3Client} from '@aws-sdk/client-s3';
|
|
5
|
+
import {ServiceQuotasClient} from '@aws-sdk/client-service-quotas';
|
|
6
|
+
import {STSClient} from '@aws-sdk/client-sts';
|
|
7
|
+
import type {CustomCredentials} from '@remotion/serverless-client';
|
|
8
|
+
import {MAX_FUNCTIONS_PER_RENDER, random} from '@remotion/serverless-client';
|
|
9
|
+
import type {AwsProvider} from './aws-provider';
|
|
10
|
+
import {checkCredentials} from './check-credentials';
|
|
11
|
+
import {getCredentials} from './get-credentials';
|
|
12
|
+
import {getEnvVariable} from './get-env-variable';
|
|
13
|
+
import type {AwsRegion} from './regions';
|
|
14
|
+
|
|
15
|
+
export type ServiceMapping = {
|
|
16
|
+
s3: S3Client;
|
|
17
|
+
cloudwatch: CloudWatchLogsClient;
|
|
18
|
+
iam: IAMClient;
|
|
19
|
+
lambda: LambdaClient;
|
|
20
|
+
servicequotas: ServiceQuotasClient;
|
|
21
|
+
sts: STSClient;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getCredentialsHash = ({
|
|
25
|
+
customCredentials,
|
|
26
|
+
region,
|
|
27
|
+
service,
|
|
28
|
+
forcePathStyle,
|
|
29
|
+
}: {
|
|
30
|
+
region: AwsRegion;
|
|
31
|
+
customCredentials: CustomCredentials<AwsProvider> | null;
|
|
32
|
+
service: keyof ServiceMapping;
|
|
33
|
+
forcePathStyle: boolean;
|
|
34
|
+
}): string => {
|
|
35
|
+
const hashComponents: {[key: string]: unknown} = {};
|
|
36
|
+
|
|
37
|
+
if (getEnvVariable('REMOTION_SKIP_AWS_CREDENTIALS_CHECK')) {
|
|
38
|
+
hashComponents.credentials = {
|
|
39
|
+
credentialsSkipped: true,
|
|
40
|
+
};
|
|
41
|
+
} else if (getEnvVariable('REMOTION_AWS_PROFILE')) {
|
|
42
|
+
hashComponents.credentials = {
|
|
43
|
+
awsProfile: getEnvVariable('REMOTION_AWS_PROFILE'),
|
|
44
|
+
};
|
|
45
|
+
} else if (
|
|
46
|
+
getEnvVariable('REMOTION_AWS_ACCESS_KEY_ID') &&
|
|
47
|
+
getEnvVariable('REMOTION_AWS_SECRET_ACCESS_KEY')
|
|
48
|
+
) {
|
|
49
|
+
hashComponents.credentials = {
|
|
50
|
+
accessKeyId: getEnvVariable('REMOTION_AWS_ACCESS_KEY_ID'),
|
|
51
|
+
secretAccessKey: getEnvVariable('REMOTION_AWS_SECRET_ACCESS_KEY'),
|
|
52
|
+
};
|
|
53
|
+
} else if (getEnvVariable('AWS_PROFILE')) {
|
|
54
|
+
hashComponents.credentials = {
|
|
55
|
+
awsProfile: getEnvVariable('AWS_PROFILE'),
|
|
56
|
+
};
|
|
57
|
+
} else if (
|
|
58
|
+
getEnvVariable('AWS_ACCESS_KEY_ID') &&
|
|
59
|
+
getEnvVariable('AWS_SECRET_ACCESS_KEY')
|
|
60
|
+
) {
|
|
61
|
+
hashComponents.credentials = {
|
|
62
|
+
accessKeyId: getEnvVariable('AWS_ACCESS_KEY_ID') as string,
|
|
63
|
+
secretAccessKey: getEnvVariable('AWS_SECRET_ACCESS_KEY') as string,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
hashComponents.customCredentials = customCredentials;
|
|
68
|
+
hashComponents.region = region;
|
|
69
|
+
hashComponents.service = service;
|
|
70
|
+
hashComponents.forcePathStyle = forcePathStyle;
|
|
71
|
+
|
|
72
|
+
return random(JSON.stringify(hashComponents)).toString().replace('0.', '');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const _clients: Partial<
|
|
76
|
+
Record<
|
|
77
|
+
string,
|
|
78
|
+
| CloudWatchLogsClient
|
|
79
|
+
| LambdaClient
|
|
80
|
+
| S3Client
|
|
81
|
+
| IAMClient
|
|
82
|
+
| ServiceQuotasClient
|
|
83
|
+
| STSClient
|
|
84
|
+
>
|
|
85
|
+
> = {};
|
|
86
|
+
|
|
87
|
+
export const getServiceClient = <T extends keyof ServiceMapping>({
|
|
88
|
+
region,
|
|
89
|
+
service,
|
|
90
|
+
customCredentials,
|
|
91
|
+
forcePathStyle,
|
|
92
|
+
}: {
|
|
93
|
+
region: AwsRegion;
|
|
94
|
+
service: T;
|
|
95
|
+
customCredentials: CustomCredentials<AwsProvider> | null;
|
|
96
|
+
forcePathStyle: boolean;
|
|
97
|
+
}): ServiceMapping[T] => {
|
|
98
|
+
const Client = (() => {
|
|
99
|
+
if (service === 'cloudwatch') {
|
|
100
|
+
return CloudWatchLogsClient;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (service === 'lambda') {
|
|
104
|
+
return LambdaClient;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (service === 's3') {
|
|
108
|
+
return S3Client;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (service === 'iam') {
|
|
112
|
+
return IAMClient;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (service === 'servicequotas') {
|
|
116
|
+
return ServiceQuotasClient;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (service === 'sts') {
|
|
120
|
+
return STSClient;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
throw new TypeError('unknown client ' + service);
|
|
124
|
+
})();
|
|
125
|
+
|
|
126
|
+
const key = getCredentialsHash({
|
|
127
|
+
region,
|
|
128
|
+
customCredentials,
|
|
129
|
+
service,
|
|
130
|
+
forcePathStyle,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (!_clients[key]) {
|
|
134
|
+
checkCredentials();
|
|
135
|
+
|
|
136
|
+
const lambdaOptions =
|
|
137
|
+
service === 'lambda'
|
|
138
|
+
? {
|
|
139
|
+
httpsAgent: {
|
|
140
|
+
maxSockets: MAX_FUNCTIONS_PER_RENDER * 2,
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
: undefined;
|
|
144
|
+
|
|
145
|
+
const client = customCredentials
|
|
146
|
+
? new Client({
|
|
147
|
+
region: customCredentials.region ?? 'us-east-1',
|
|
148
|
+
credentials:
|
|
149
|
+
customCredentials.accessKeyId && customCredentials.secretAccessKey
|
|
150
|
+
? {
|
|
151
|
+
accessKeyId: customCredentials.accessKeyId,
|
|
152
|
+
secretAccessKey: customCredentials.secretAccessKey,
|
|
153
|
+
}
|
|
154
|
+
: undefined,
|
|
155
|
+
endpoint: customCredentials.endpoint,
|
|
156
|
+
requestHandler: lambdaOptions,
|
|
157
|
+
forcePathStyle: customCredentials.forcePathStyle,
|
|
158
|
+
})
|
|
159
|
+
: getEnvVariable('REMOTION_SKIP_AWS_CREDENTIALS_CHECK')
|
|
160
|
+
? new Client({
|
|
161
|
+
region,
|
|
162
|
+
requestHandler: lambdaOptions,
|
|
163
|
+
})
|
|
164
|
+
: new Client({
|
|
165
|
+
region,
|
|
166
|
+
credentials: getCredentials(),
|
|
167
|
+
requestHandler: lambdaOptions,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (getEnvVariable('REMOTION_DISABLE_AWS_CLIENT_CACHE')) {
|
|
171
|
+
return client as ServiceMapping[T];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
_clients[key] = client;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return _clients[key] as ServiceMapping[T];
|
|
178
|
+
};
|
package/src/get-sites.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type {ProviderSpecifics} from '@remotion/serverless-client';
|
|
2
|
+
import type {AwsProvider} from './aws-provider';
|
|
3
|
+
import {awsImplementation} from './aws-provider';
|
|
4
|
+
import {getSitesKey} from './constants';
|
|
5
|
+
import type {BucketWithLocation} from './get-buckets';
|
|
6
|
+
import {makeS3ServeUrl} from './make-s3-url';
|
|
7
|
+
import type {AwsRegion} from './regions';
|
|
8
|
+
|
|
9
|
+
type Site = {
|
|
10
|
+
sizeInBytes: number;
|
|
11
|
+
lastModified: number | null;
|
|
12
|
+
bucketName: string;
|
|
13
|
+
id: string;
|
|
14
|
+
serveUrl: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type MandatoryParameters = {
|
|
18
|
+
region: AwsRegion;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type OptionalParameters = {
|
|
22
|
+
forceBucketName: string | null;
|
|
23
|
+
forcePathStyle: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type GetSitesInternalInput = MandatoryParameters & OptionalParameters;
|
|
27
|
+
export type GetSitesInput = MandatoryParameters & Partial<OptionalParameters>;
|
|
28
|
+
|
|
29
|
+
export type GetSitesOutput = {
|
|
30
|
+
sites: Site[];
|
|
31
|
+
buckets: BucketWithLocation[];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const internalGetSites = async ({
|
|
35
|
+
region,
|
|
36
|
+
forceBucketName,
|
|
37
|
+
providerSpecifics,
|
|
38
|
+
forcePathStyle,
|
|
39
|
+
}: GetSitesInternalInput & {
|
|
40
|
+
providerSpecifics: ProviderSpecifics<AwsProvider>;
|
|
41
|
+
}): Promise<GetSitesOutput> => {
|
|
42
|
+
const remotionBuckets = forceBucketName
|
|
43
|
+
? await providerSpecifics.getBuckets({
|
|
44
|
+
region,
|
|
45
|
+
forceBucketName,
|
|
46
|
+
forcePathStyle,
|
|
47
|
+
})
|
|
48
|
+
: await providerSpecifics.getBuckets({
|
|
49
|
+
region,
|
|
50
|
+
forceBucketName: null,
|
|
51
|
+
forcePathStyle,
|
|
52
|
+
});
|
|
53
|
+
const accountId = await providerSpecifics.getAccountId({region});
|
|
54
|
+
|
|
55
|
+
const sites: {[key: string]: Site} = {};
|
|
56
|
+
|
|
57
|
+
for (const bucket of remotionBuckets) {
|
|
58
|
+
const ls = await providerSpecifics.listObjects({
|
|
59
|
+
bucketName: bucket.name,
|
|
60
|
+
prefix: getSitesKey(''),
|
|
61
|
+
region,
|
|
62
|
+
expectedBucketOwner: accountId,
|
|
63
|
+
forcePathStyle,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
for (const file of ls) {
|
|
67
|
+
const siteKeyMatch = file.Key?.match(
|
|
68
|
+
/sites\/([0-9a-zA-Z-!_.*'()]+)\/(.*)$/,
|
|
69
|
+
);
|
|
70
|
+
if (!siteKeyMatch) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`A file was found in the bucket "${bucket.name}" with the key ${file.Key} which is an unexpected folder structure. Delete this file.`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const [, siteId] = siteKeyMatch;
|
|
77
|
+
if (!sites[siteId]) {
|
|
78
|
+
sites[siteId] = {
|
|
79
|
+
sizeInBytes: 0,
|
|
80
|
+
bucketName: bucket.name,
|
|
81
|
+
lastModified: null,
|
|
82
|
+
id: siteId,
|
|
83
|
+
serveUrl: makeS3ServeUrl({
|
|
84
|
+
bucketName: bucket.name,
|
|
85
|
+
region,
|
|
86
|
+
subFolder: getSitesKey(siteId),
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (file.LastModified) {
|
|
92
|
+
const currentLastModified = sites[siteId].lastModified;
|
|
93
|
+
if (
|
|
94
|
+
currentLastModified === null ||
|
|
95
|
+
file.LastModified.getTime() > currentLastModified
|
|
96
|
+
) {
|
|
97
|
+
sites[siteId].lastModified = file.LastModified.getTime();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (file.Size) {
|
|
102
|
+
sites[siteId].sizeInBytes += file.Size;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const sitesArray: Site[] = Object.keys(sites).map((siteId) => {
|
|
108
|
+
return sites[siteId];
|
|
109
|
+
});
|
|
110
|
+
return {sites: sitesArray, buckets: remotionBuckets};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
* @description Gets an array of Remotion projects in Cloud Storage, in your GCP project.
|
|
115
|
+
* @see [Documentation](https://remotion.dev/docs/cloudrun/getsites)
|
|
116
|
+
*/
|
|
117
|
+
export const getSites = ({
|
|
118
|
+
region,
|
|
119
|
+
forceBucketName,
|
|
120
|
+
forcePathStyle,
|
|
121
|
+
}: GetSitesInput): Promise<GetSitesOutput> => {
|
|
122
|
+
return internalGetSites({
|
|
123
|
+
region,
|
|
124
|
+
forceBucketName: forceBucketName ?? null,
|
|
125
|
+
forcePathStyle: forcePathStyle ?? false,
|
|
126
|
+
providerSpecifics: awsImplementation,
|
|
127
|
+
});
|
|
128
|
+
};
|
package/src/head-file.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {HeadObjectCommand} 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 lambdaHeadFileImplementation: ProviderSpecifics<AwsProvider>['headFile'] =
|
|
7
|
+
async ({
|
|
8
|
+
bucketName,
|
|
9
|
+
key,
|
|
10
|
+
region,
|
|
11
|
+
customCredentials,
|
|
12
|
+
forcePathStyle,
|
|
13
|
+
}): Promise<{
|
|
14
|
+
LastModified?: Date | undefined;
|
|
15
|
+
ContentLength?: number | undefined;
|
|
16
|
+
}> => {
|
|
17
|
+
const head = await getS3Client({
|
|
18
|
+
region,
|
|
19
|
+
customCredentials,
|
|
20
|
+
forcePathStyle,
|
|
21
|
+
}).send(
|
|
22
|
+
new HeadObjectCommand({
|
|
23
|
+
Bucket: bucketName,
|
|
24
|
+
Key: key,
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
return head;
|
|
28
|
+
};
|