diff --git a/packages/ai-improvements/.jsdoc/approuterwebhook b/packages/ai-improvements/.jsdoc/approuterwebhook new file mode 100644 index 0000000000..af5a94ac24 --- /dev/null +++ b/packages/ai-improvements/.jsdoc/approuterwebhook @@ -0,0 +1,4 @@ +/** + * @description Simplifies the process of setting up a Lambda Webhook in your Next.js app which is using App Router. + * @see [Documentation](https://www.remotion.dev/docs/lambda/approuterwebhook) + */ \ No newline at end of file diff --git a/packages/ai-improvements/.jsdoc/pagesrouterwebhook b/packages/ai-improvements/.jsdoc/pagesrouterwebhook new file mode 100644 index 0000000000..85f371ef24 --- /dev/null +++ b/packages/ai-improvements/.jsdoc/pagesrouterwebhook @@ -0,0 +1,4 @@ +/** + * @description Simplifies the process of setting up a Lambda Webhook in your Next.js app which is using Pages Router. + * @see [Documentation](https://www.remotion.dev/docs/lambda/pagesrouterwebhook) + */ \ No newline at end of file diff --git a/packages/docs/components/TableOfContents/lambda.tsx b/packages/docs/components/TableOfContents/lambda.tsx index e62c4d65ed..a34917f2e9 100644 --- a/packages/docs/components/TableOfContents/lambda.tsx +++ b/packages/docs/components/TableOfContents/lambda.tsx @@ -1,100 +1,112 @@ -import React from "react"; -import { Grid } from "./Grid"; -import { TOCItem } from "./TOCItem"; +import React from 'react'; +import {Grid} from './Grid'; +import {TOCItem} from './TOCItem'; export const TableOfContents: React.FC = () => { - return ( -
- - - estimatePrice() -
Estimate the price of a render
-
- - deployFunction() -
Create a new function in AWS Lambda
-
- - deleteFunction() -
Delete a function in AWS Lambda
-
- - getFunctionInfo() -
Gets information about a function
-
- - getFunctions() -
Lists available Remotion Lambda functions
-
- - getCompositionsOnLambda() -
Gets list of compositions inside a Lambda function
-
- - deleteSite() -
Delete a bundle from S3
-
- - deploySite() -
Bundle and upload a site to S3
-
- - getAwsClient() -
Access the AWS SDK directly
-
- - getRegions() -
Get all available regions
-
- - getSites() -
Get all available sites
-
- - downloadMedia() -
Download a render artifact from S3
-
- - getUserPolicy() -
Get the policy JSON for your AWS user
-
- - getRolePolicy() -
Get the policy JSON for your AWS role
-
- - getOrCreateBucket() -
Ensure a Remotion S3 bucket exists
-
- - getRenderProgress() -
Query the progress of a render
-
- - presignUrl() -
Make a private file public to those with the link
-
- - renderMediaOnLambda() -
Trigger a video or audio render
-
- - renderStillOnLambda() -
Trigger a still render
-
- - simulatePermissions() -
Ensure permissions are correctly set up
-
- - speculateFunctionName() -
Get the lambda function name based on its configuration
-
- - validateWebhookSignature() -
Validate an incoming webhook request is authentic
-
-
-
- ); + return ( +
+ + + estimatePrice() +
Estimate the price of a render
+
+ + deployFunction() +
Create a new function in AWS Lambda
+
+ + deleteFunction() +
Delete a function in AWS Lambda
+
+ + getFunctionInfo() +
Gets information about a function
+
+ + getFunctions() +
Lists available Remotion Lambda functions
+
+ + getCompositionsOnLambda() +
Gets list of compositions inside a Lambda function
+
+ + deleteSite() +
Delete a bundle from S3
+
+ + deploySite() +
Bundle and upload a site to S3
+
+ + getAwsClient() +
Access the AWS SDK directly
+
+ + getRegions() +
Get all available regions
+
+ + getSites() +
Get all available sites
+
+ + downloadMedia() +
Download a render artifact from S3
+
+ + getUserPolicy() +
Get the policy JSON for your AWS user
+
+ + getRolePolicy() +
Get the policy JSON for your AWS role
+
+ + getOrCreateBucket() +
Ensure a Remotion S3 bucket exists
+
+ + getRenderProgress() +
Query the progress of a render
+
+ + presignUrl() +
Make a private file public to those with the link
+
+ + renderMediaOnLambda() +
Trigger a video or audio render
+
+ + renderStillOnLambda() +
Trigger a still render
+
+ + simulatePermissions() +
Ensure permissions are correctly set up
+
+ + speculateFunctionName() +
Get the lambda function name based on its configuration
+
+ + validateWebhookSignature() +
Validate an incoming webhook request is authentic
+
+ + appRouterWebhook() +
+ Handle incoming webhooks specifically for the Next.js app router +
+
+ + pagesRouterWebhook() +
+ Handle incoming webhooks specifically for the Next.js pages router +
+
+
+
+ ); }; diff --git a/packages/docs/docs/lambda/approuterwebhook.mdx b/packages/docs/docs/lambda/approuterwebhook.mdx new file mode 100644 index 0000000000..8e97e68689 --- /dev/null +++ b/packages/docs/docs/lambda/approuterwebhook.mdx @@ -0,0 +1,65 @@ +--- +image: /generated/articles-docs-lambda-approuterwebhook.png +id: approuterwebhook +title: appRouterWebhook() +slug: /lambda/approuterwebhook +crumb: 'Lambda API' +--- + +Simplifies the process of setting up a [Lambda Webhook](/docs/lambda/webhooks) in your Next.js app which is using App Router. Refer to [`pagesRouterWebhook()`](/docs/lambda/pagesrouterwebhook) for doing the same in apps using Pages Router. + +## API + +The function accepts an object with six key-value pairs: + +### `secret` + +Your webhook secret, must be a `string` + +### `testing` + +Whether or not to allow requests intending to test the endpoint, useful while using Webhook endpoint tester on [Webhooks Page](/docs/lambda/webhooks). Should be a `boolean`. + +### `extraHeaders` + +Add your own custom headers to the outgoing response. Provide key-value pairs where both the key and value are strings. + +### `onSuccess()` + +A function that is called with a [`WebhookSuccessPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates a successful event. + +### `onError()` + +A function that is called with a [`WebhookErrorPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates an error. + +### `onTimeout()` + +A function that is called with a [`WebhookTimeoutPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates a timeout. + +## Example + +Setting up a webhook endpoint in a Next.js app which uses App Router. This will listen on the endpoint: `mydomain.com/api` + +```tsx twoslash title="app/api/route.ts" +import {appRouterWebhook} from '@remotion/lambda/client'; + +export const POST = appRouterWebhook({ + secret: 'mysecret', + testing: true, + extraHeaders: { + region: 'south-asia', + }, + onSuccess: () => console.log('Rendering Completed Successfully'), + onError: () => console.log('Something went wrong while rendering'), + onTimeout: () => console.log('Timeout occured while rendering'), +}); + +export const OPTIONS = POST; +``` + +See [Webhooks](/docs/lambda/webhooks) for an Express example. + +## See also + +- [Webhooks](/docs/lambda/webhooks) +- [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/lambda/src/api/app-router-webhook.ts) diff --git a/packages/docs/docs/lambda/pagesrouterwebhooks.mdx b/packages/docs/docs/lambda/pagesrouterwebhooks.mdx new file mode 100644 index 0000000000..c15281607d --- /dev/null +++ b/packages/docs/docs/lambda/pagesrouterwebhooks.mdx @@ -0,0 +1,64 @@ +--- +image: /generated/articles-docs-lambda-pagesrouterwebhooks.png +id: pagesrouterwebhook +title: pagesRouterWebhook() +slug: /lambda/pagesrouterwebhook +crumb: 'Lambda API' +--- + +Simplifies the process of setting up a [Lambda Webhook](/docs/lambda/webhooks) in your Next.js app which is using Pages Router. Similar to [`appRouterWebhook()`](/docs/lambda/approuterwebhook). + +## API + +The function accepts an object with six key-value pairs: + +### `secret` + +Your webhook secret, must be a `string` + +### `testing` + +Whether or not to allow requests intending to test the endpoint, useful while using Webhook endpoint tester on [Webhooks Page](/docs/lambda/webhooks). Should be a `boolean`. + +### `extraHeaders` + +Add your own custom headers to the outgoing response. Provide key-value pairs where both the key and value are strings. + +### `onSuccess()` + +A function that is called with a [`WebhookSuccessPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates a successful event. + +### `onError()` + +A function that is called with a [`WebhookErrorPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates an error. + +### `onTimeout()` + +A function that is called with a [`WebhookTimeoutPayload`](/docs/lambda/webhooks#response) object as an argument when the incoming request indicates a timeout. + +## Example + +Setting up a webhook endpoint in a Next.js app which uses Pages Router. This will listen on the endpoint: `mydomain.com/api/webhook` + +```tsx twoslash title="pages/api/webhook.ts" +import {pagesRouterWebhook} from '@remotion/lambda/client'; + +const handler = pagesRouterWebhook({ + secret: 'mysecret', + testing: true, + extraHeaders: { + region: 'south-asia', + }, + onSuccess: () => console.log('Rendering Completed Successfully'), + onError: () => console.log('Something went wrong while rendering'), + onTimeout: () => console.log('Timeout occured while rendering'), +}); +export default handler; +``` + +See [Webhooks](/docs/lambda/webhooks) for an Express example. + +## See also + +- [Webhooks](/docs/lambda/webhooks) +- [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/lambda/src/api/pages-router-webhook.ts) diff --git a/packages/docs/docs/lambda/webhooks.mdx b/packages/docs/docs/lambda/webhooks.mdx index e000deaf5b..ed0dc7de46 100644 --- a/packages/docs/docs/lambda/webhooks.mdx +++ b/packages/docs/docs/lambda/webhooks.mdx @@ -38,44 +38,39 @@ You can use these headers to verify the authenticity of the request, to check th The request body has the following structure: ```ts -type WebhookPayload = - | { - type: 'error'; - errors: { - message: string; - name: string; - stack: string; - }[]; - renderId: string; - expectedBucketOwner: string; - bucketName: string; - customData: Record; - } - | { - type: 'success'; - lambdaErrors: EnhancedErrorInfo[]; - outputUrl: string | undefined; - outputFile: string | undefined; - timeToFinish: number | undefined; - renderId: string; - expectedBucketOwner: string; - bucketName: string; - customData: Record; - // Available from v3.3.11 - costs: { - estimatedCost: number; - estimatedDisplayCost: string; - currency: string; - disclaimer: string; - }; - } - | { - type: 'timeout'; - renderId: string; - expectedBucketOwner: string; - bucketName: string; - customData: Record; - }; +type StaticWebhookPayload = { + renderId: string; + expectedBucketOwner: string; + bucketName: string; + customData: Record | null; +}; + +export type WebhookErrorPayload = StaticWebhookPayload & { + type: 'error'; + errors: { + message: string; + name: string; + stack: string; + }[]; +}; + +export type WebhookSuccessPayload = StaticWebhookPayload & { + type: 'success'; + lambdaErrors: EnhancedErrorInfo[]; + outputUrl: string | undefined; + outputFile: string | undefined; + timeToFinish: number | undefined; + costs: AfterRenderCost; +}; + +export type WebhookTimeoutPayload = StaticWebhookPayload & { + type: 'timeout'; +}; + +export type WebhookPayload = + | WebhookErrorPayload + | WebhookSuccessPayload + | WebhookTimeoutPayload; ``` The fields [`renderId`](/docs/lambda/rendermediaonlambda#renderid), [`bucketName`](/docs/lambda/rendermediaonlambda#bucketname) will be returned [just like they are returned by `renderMediaOnLambda()` itself](/docs/lambda/rendermediaonlambda#return-value). @@ -205,122 +200,46 @@ router.post("/my-remotion-webhook-endpoint", jsonParser, (req, res) => { ## Example webhook endpoint (Next.JS App Router) -Similary, here is an example endpoint in Next.JS for the App Router. - -Since this endpoint is going to be executed in an AWS Lambda function on its own, you want to import the Remotion functions from [`@remotion/lambda/client`](/docs/lambda/light-client). +Similarly, here is an example endpoint in Next.JS for the App Router using [`appRouterWebhook()`](/docs/lambda/approuterwebhook). Available from v4.0.246. ```tsx twoslash title="app/api/webhook.ts" -import { - validateWebhookSignature, - WebhookPayload, -} from '@remotion/lambda/client'; - -// Enable testing through the tool below -// You may disable it in production -const ENABLE_TESTING = true; +const ENABLE_TESTING = false; -export const POST = async (req: Request, res: Response) => { - let headers = {}; - - if (ENABLE_TESTING) { - const testingheaders = { - 'Access-Control-Allow-Origin': 'https://www.remotion.dev', - 'Access-Control-Allow-Headers': - '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', - 'Access-Control-Allow-Methods': 'OPTIONS,POST', - }; - headers = {...headers, ...testingheaders}; - } - - if (req.method === 'OPTIONS') { - return new Response(null, { - headers, - }); - } - - // Parse the body properly - const body = await req.json(); - - validateWebhookSignature({ - secret: process.env.WEBHOOK_SECRET as string, - body: body, - signatureHeader: req.headers.get('X-Remotion-Signature') as string, - }); - - const payload = body as WebhookPayload; - - if (payload.type === 'success') { - //... - } else if (payload.type === 'timeout') { - //... - } - - return new Response(JSON.stringify({success: true})); -}; +// ---cut--- +import {appRouterWebhook} from '@remotion/lambda/client'; + +export const POST = appRouterWebhook({ + secret: 'mysecret', + // Enable testing through the tool below + testing: ENABLE_TESTING, + onSuccess: ({renderId}) => console.log('Finished render', renderId), + onTimeout: ({renderId}) => console.log('Time out', renderId), + onError: ({renderId}) => console.log('Error', renderId), +}); export const OPTIONS = POST; ``` ## Example webhook endpoint (Next.JS Pages Router) -The same endpoint as above, but using the Pages Router. +The same endpoint as above, but using the Pages Router with the help of [`pagesRouterWebhook()`](/docs/lambda/pagesrouterwebhook). Available from v4.0.246. ```tsx twoslash title="pages/api/webhook.ts" -type NextApiRequest = { - body: object; - headers: Record; - method: string; -}; -type NextApiResponse = { - status: (code: number) => {json: (body: object) => void; end: () => void}; - setHeader: (key: string, value: string) => void; - end: () => void; -}; -// ---cut--- -import { - validateWebhookSignature, - WebhookPayload, -} from '@remotion/lambda/client'; +const ENABLE_TESTING = false; -// Enable testing through the tool below -// You may disable it in production -const ENABLE_TESTING = true; - -export default async function handler( - req: NextApiRequest, - res: NextApiResponse, -) { - if (ENABLE_TESTING) { - res.setHeader('Access-Control-Allow-Origin', 'https://www.remotion.dev'); - res.setHeader('Access-Control-Allow-Methods', 'OPTIONS,POST'); - res.setHeader( - 'Access-Control-Allow-Headers', - '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', - ); - } - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - - validateWebhookSignature({ - secret: process.env.WEBHOOK_SECRET as string, - body: req.body, - signatureHeader: req.headers['x-remotion-signature'] as string, - }); +// ---cut--- - // If code reaches this path, the webhook is authentic. - const payload = req.body as WebhookPayload; - if (payload.type === 'success') { - // ... - } else if (payload.type === 'timeout') { - // ... - } +import {pagesRouterWebhook} from '@remotion/lambda/client'; - res.status(200).json({ - success: true, - }); -} +const handler = pagesRouterWebhook({ + secret: 'mysecret', + // Enable testing through the tool below + testing: ENABLE_TESTING, + onSuccess: ({renderId}) => console.log('Finished render', renderId), + onTimeout: ({renderId}) => console.log('Time out', renderId), + onError: ({renderId}) => console.log('Error', renderId), +}); +export default handler; ``` ## Test your webhook endpoint diff --git a/packages/docs/sidebars.js b/packages/docs/sidebars.js index 2571bbd442..24bd37310b 100644 --- a/packages/docs/sidebars.js +++ b/packages/docs/sidebars.js @@ -250,6 +250,8 @@ module.exports = { 'lambda/simulatepermissions', 'lambda/speculatefunctionname', 'lambda/validatewebhooksignature', + 'lambda/approuterwebhook', + 'lambda/pagesrouterwebhook', ], }, { diff --git a/packages/docs/src/data/articles.ts b/packages/docs/src/data/articles.ts index f775435d47..35c8ea8bcf 100644 --- a/packages/docs/src/data/articles.ts +++ b/packages/docs/src/data/articles.ts @@ -1439,6 +1439,15 @@ export const articles = [ noAi: false, slug: 'lambda/api', }, + { + id: 'approuterwebhook', + title: 'appRouterWebhook()', + relativePath: 'docs/lambda/approuterwebhook.mdx', + compId: 'articles-docs-lambda-approuterwebhook', + crumb: 'Lambda API', + noAi: false, + slug: 'lambda/approuterwebhook', + }, { id: 'authentication', title: 'Authentication', @@ -1871,6 +1880,15 @@ export const articles = [ noAi: false, slug: 'lambda/naming-convention', }, + { + id: 'pagesrouterwebhook', + title: 'pagesRouterWebhook()', + relativePath: 'docs/lambda/pagesrouterwebhooks.mdx', + compId: 'articles-docs-lambda-pagesrouterwebhooks', + crumb: 'Lambda API', + noAi: false, + slug: 'lambda/pagesrouterwebhook', + }, { id: 'lambda/permissions', title: 'Permissions', diff --git a/packages/docs/static/generated/articles-docs-lambda-approuterwebhook.png b/packages/docs/static/generated/articles-docs-lambda-approuterwebhook.png new file mode 100644 index 0000000000..f0747a3709 Binary files /dev/null and b/packages/docs/static/generated/articles-docs-lambda-approuterwebhook.png differ diff --git a/packages/docs/static/generated/articles-docs-lambda-pagesrouterwebhooks.png b/packages/docs/static/generated/articles-docs-lambda-pagesrouterwebhooks.png new file mode 100644 index 0000000000..fbe3488a81 Binary files /dev/null and b/packages/docs/static/generated/articles-docs-lambda-pagesrouterwebhooks.png differ diff --git a/packages/lambda/package.json b/packages/lambda/package.json index e69fa7894c..65ad8e1c84 100644 --- a/packages/lambda/package.json +++ b/packages/lambda/package.json @@ -46,6 +46,7 @@ "@types/prompt": "^1.1.0", "pureimage": "0.4.13", "zip-lib": "^0.7.2", + "next": "15.1.2", "@remotion/eslint-config-internal": "workspace:*", "eslint": "9.14.0" }, diff --git a/packages/lambda/src/api/app-router-webhook.ts b/packages/lambda/src/api/app-router-webhook.ts new file mode 100644 index 0000000000..9ffbee9ae2 --- /dev/null +++ b/packages/lambda/src/api/app-router-webhook.ts @@ -0,0 +1,64 @@ +import type { + WebhookErrorPayload, + WebhookPayload, + WebhookSuccessPayload, + WebhookTimeoutPayload, +} from '@remotion/serverless'; +import {validateWebhookSignature} from './validate-webhook-signature'; + +export type NextWebhookArgs = { + testing?: boolean; + extraHeaders?: Record; + secret: string; + onSuccess?: (payload: WebhookSuccessPayload) => void; + onTimeout?: (payload: WebhookTimeoutPayload) => void; + onError?: (payload: WebhookErrorPayload) => void; +}; + +export const appRouterWebhook = ( + options: NextWebhookArgs, +): ((req: Request) => Promise) => { + const {testing, extraHeaders, secret, onSuccess, onTimeout, onError} = + options; + return async function (req: Request): Promise { + let headers = extraHeaders || {}; + + if (testing) { + const testingheaders = { + 'Access-Control-Allow-Origin': 'https://www.remotion.dev', + 'Access-Control-Allow-Headers': + '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', + 'Access-Control-Allow-Methods': 'OPTIONS,POST', + }; + headers = {...headers, ...testingheaders}; + } + + if (req.method === 'OPTIONS') { + // 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 + return new Response(null, { + headers, + }); + } + + // Parse the body properly + const body = await req.json(); + + validateWebhookSignature({ + secret, + body, + signatureHeader: req.headers.get('X-Remotion-Signature') as string, + }); + + const payload = body as WebhookPayload; + + if (payload.type === 'success' && onSuccess) { + onSuccess(payload); + } else if (payload.type === 'timeout' && onTimeout) { + onTimeout(payload); + } else if (payload.type === 'error' && onError) { + onError(payload); + } + + return new Response(JSON.stringify({success: true}), {headers}); + }; +}; diff --git a/packages/lambda/src/api/pages-router-webhook.ts b/packages/lambda/src/api/pages-router-webhook.ts new file mode 100644 index 0000000000..8eeceaa9f5 --- /dev/null +++ b/packages/lambda/src/api/pages-router-webhook.ts @@ -0,0 +1,54 @@ +import type {WebhookPayload} from '@remotion/serverless'; +import type {NextApiRequest, NextApiResponse} from 'next'; +import type {NextWebhookArgs} from './app-router-webhook'; +import {validateWebhookSignature} from './validate-webhook-signature'; + +const addHeaders = (res: NextApiResponse, headers: Record) => { + Object.entries(headers).forEach(([key, value]) => { + res.setHeader(key, value); + }); +}; + +export const pagesRouterWebhook = (options: NextWebhookArgs) => { + const {testing, extraHeaders, secret, onSuccess, onTimeout, onError} = + options; + return function (req: NextApiRequest, res: NextApiResponse): void { + addHeaders(res, extraHeaders || {}); + + if (testing) { + const testingheaders = { + 'Access-Control-Allow-Origin': 'https://www.remotion.dev', + 'Access-Control-Allow-Headers': + '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', + 'Access-Control-Allow-Methods': 'OPTIONS,POST', + }; + + addHeaders(res, testingheaders); + } + + if (req.method === 'OPTIONS') { + res.status(200).end(); + return; + } + + validateWebhookSignature({ + secret, + body: req.body, + signatureHeader: req.headers['x-remotion-signature'] as string, + }); + + // If code reaches this path, the webhook is authentic. + const payload = req.body as WebhookPayload; + if (payload.type === 'success' && onSuccess) { + onSuccess(payload); + } else if (payload.type === 'timeout' && onTimeout) { + onTimeout(payload); + } else if (payload.type === 'error' && onError) { + onError(payload); + } + + res.status(200).json({ + success: true, + }); + }; +}; diff --git a/packages/lambda/src/client.ts b/packages/lambda/src/client.ts index da235e1736..3ca527432c 100644 --- a/packages/lambda/src/client.ts +++ b/packages/lambda/src/client.ts @@ -1,59 +1,47 @@ -import type {DeleteRenderInput} from './api/delete-render'; -import {deleteRender} from './api/delete-render'; -import {getCompositionsOnLambda} from './api/get-compositions-on-lambda'; -import {getFunctions} from './api/get-functions'; -import type {GetRenderProgressInput} from './api/get-render-progress'; -import {getRenderProgress} from './api/get-render-progress'; -import {getSites} from './api/get-sites'; -import type {PresignUrlInput} from './api/presign-url'; -import {presignUrl} from './api/presign-url'; -import type { - RenderMediaOnLambdaInput, - RenderMediaOnLambdaOutput, -} from './api/render-media-on-lambda'; -import { - renderMediaOnLambda, - renderVideoOnLambda, -} from './api/render-media-on-lambda'; -import type { - RenderStillOnLambdaInput, - RenderStillOnLambdaOutput, -} from './api/render-still-on-lambda'; -import {renderStillOnLambda} from './api/render-still-on-lambda'; -import type {SpeculateFunctionNameInput} from './api/speculate-function-name'; -import {speculateFunctionName} from './api/speculate-function-name'; -import {validateWebhookSignature} from './api/validate-webhook-signature'; -import type {RenderProgress} from './shared/constants'; -export type {WebhookPayload} from '@remotion/serverless'; - +export type { + WebhookErrorPayload, + WebhookPayload, + WebhookSuccessPayload, + WebhookTimeoutPayload, +} from '@remotion/serverless'; export type {CustomCredentials, DeleteAfter} from '@remotion/serverless/client'; +export {NextWebhookArgs, appRouterWebhook} from './api/app-router-webhook'; +export {deleteRender, type DeleteRenderInput} from './api/delete-render'; export { getAwsClient, type GetAwsClientInput, type GetAwsClientOutput, } from './api/get-aws-client'; -export type {AwsRegion} from './regions'; export { - deleteRender, getCompositionsOnLambda, - getFunctions, - getRenderProgress, + type GetCompositionsOnLambdaInput, + type GetCompositionsOnLambdaOutput, +} from './api/get-compositions-on-lambda'; +export {getFunctions, type GetFunctionsInput} from './api/get-functions'; +export {getRenderProgress} from './api/get-render-progress'; +export type {GetRenderProgressInput} from './api/get-render-progress'; +export { getSites, - presignUrl, + type GetSitesInput, + type GetSitesOutput, +} from './api/get-sites'; +export {pagesRouterWebhook} from './api/pages-router-webhook'; +export {presignUrl, type PresignUrlInput} from './api/presign-url'; +export { renderMediaOnLambda, - renderStillOnLambda, renderVideoOnLambda, + type RenderMediaOnLambdaInput, + type RenderMediaOnLambdaOutput, +} from './api/render-media-on-lambda'; +export { + renderStillOnLambda, + type RenderStillOnLambdaInput, + type RenderStillOnLambdaOutput, +} from './api/render-still-on-lambda'; +export { speculateFunctionName, - validateWebhookSignature, -}; -export type { - DeleteRenderInput, - GetRenderProgressInput, - PresignUrlInput, - RenderMediaOnLambdaInput, - RenderMediaOnLambdaOutput, - RenderProgress, - RenderStillOnLambdaInput, - RenderStillOnLambdaOutput, - SpeculateFunctionNameInput, -}; + type SpeculateFunctionNameInput, +} from './api/speculate-function-name'; +export {validateWebhookSignature} from './api/validate-webhook-signature'; +export type {AwsRegion} from './regions'; +export type {RenderProgress} from './shared/constants'; diff --git a/packages/serverless/src/index.ts b/packages/serverless/src/index.ts index 2b3e8107e1..99dc8a72fa 100644 --- a/packages/serverless/src/index.ts +++ b/packages/serverless/src/index.ts @@ -15,7 +15,14 @@ export {stillHandler} from './handlers/still'; export {infoHandler} from './info'; export {innerHandler} from './inner-routine'; export {inspectErrors} from './inspect-error'; -export {WebhookClient, WebhookPayload, invokeWebhook} from './invoke-webhook'; +export { + WebhookClient, + WebhookErrorPayload, + WebhookPayload, + WebhookSuccessPayload, + WebhookTimeoutPayload, + invokeWebhook, +} from './invoke-webhook'; export {setCurrentRequestId, stopLeakDetection} from './leak-detection'; export { OVERHEAD_TIME_PER_LAMBDA, diff --git a/packages/serverless/src/invoke-webhook.ts b/packages/serverless/src/invoke-webhook.ts index 9fd032320f..a945fe3bec 100644 --- a/packages/serverless/src/invoke-webhook.ts +++ b/packages/serverless/src/invoke-webhook.ts @@ -16,33 +16,39 @@ export function calculateSignature(payload: string, secret: string | null) { return signature; } -type DynamicWebhookPayload = - | { - type: 'error'; - errors: { - message: string; - name: string; - stack: string; - }[]; - } - | { - type: 'success'; - lambdaErrors: EnhancedErrorInfo[]; - outputUrl: string | undefined; - outputFile: string | undefined; - timeToFinish: number | undefined; - costs: AfterRenderCost; - } - | { - type: 'timeout'; - }; - -export type WebhookPayload = { +type StaticWebhookPayload = { renderId: string; expectedBucketOwner: string; bucketName: string; customData: Record | null; -} & DynamicWebhookPayload; +}; + +export type WebhookErrorPayload = StaticWebhookPayload & { + type: 'error'; + errors: { + message: string; + name: string; + stack: string; + }[]; +}; + +export type WebhookSuccessPayload = StaticWebhookPayload & { + type: 'success'; + lambdaErrors: EnhancedErrorInfo[]; + outputUrl: string | undefined; + outputFile: string | undefined; + timeToFinish: number | undefined; + costs: AfterRenderCost; +}; + +export type WebhookTimeoutPayload = StaticWebhookPayload & { + type: 'timeout'; +}; + +export type WebhookPayload = + | WebhookErrorPayload + | WebhookSuccessPayload + | WebhookTimeoutPayload; // Don't handle 304 status code (Not Modified) as a redirect, // since the browser will display the right page. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62b771f206..2bc11a9961 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1385,6 +1385,9 @@ importers: eslint: specifier: 9.14.0 version: 9.14.0 + next: + specifier: 15.1.2 + version: 15.1.2(@babel/core@7.23.2)(react-dom@19.0.0)(react@19.0.0) pureimage: specifier: 0.4.13 version: 0.4.13 @@ -3390,7 +3393,7 @@ packages: '@aws-sdk/types': 3.609.0 '@aws-sdk/util-locate-window': 3.49.0 '@smithy/util-utf8': 2.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-crypto/sha256-browser@5.2.0: @@ -3402,7 +3405,7 @@ packages: '@aws-sdk/types': 3.609.0 '@aws-sdk/util-locate-window': 3.49.0 '@smithy/util-utf8': 2.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-crypto/sha256-js@5.2.0: @@ -3411,7 +3414,7 @@ packages: dependencies: '@aws-crypto/util': 5.2.0 '@aws-sdk/types': 3.609.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-crypto/supports-web-crypto@5.2.0: @@ -3525,7 +3528,7 @@ packages: '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - aws-crt dev: false @@ -3794,7 +3797,7 @@ packages: '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - aws-crt dev: false @@ -3888,7 +3891,7 @@ packages: '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - aws-crt dev: false @@ -3906,7 +3909,7 @@ packages: '@smithy/types': 3.3.0 '@smithy/util-middleware': 3.0.3 fast-xml-parser: 4.4.1 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/credential-provider-cognito-identity@3.645.0: @@ -3917,7 +3920,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - aws-crt dev: false @@ -3929,7 +3932,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/credential-provider-http@3.635.0: @@ -3944,7 +3947,7 @@ packages: '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/util-stream': 3.1.3 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/credential-provider-ini@3.645.0(@aws-sdk/client-sso-oidc@3.645.0)(@aws-sdk/client-sts@3.645.0): @@ -3964,7 +3967,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - aws-crt @@ -3985,7 +3988,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - '@aws-sdk/client-sts' @@ -4000,7 +4003,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/credential-provider-sso@3.645.0(@aws-sdk/client-sso-oidc@3.645.0): @@ -4083,7 +4086,7 @@ packages: '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-expect-continue@3.620.0: @@ -4093,7 +4096,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-flexible-checksums@3.620.0: @@ -4107,7 +4110,7 @@ packages: '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-host-header@3.620.0: @@ -4117,7 +4120,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-location-constraint@3.609.0: @@ -4126,7 +4129,7 @@ packages: dependencies: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-logger@3.609.0: @@ -4135,7 +4138,7 @@ packages: dependencies: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-recursion-detection@3.620.0: @@ -4145,7 +4148,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-sdk-s3@3.635.0: @@ -4165,7 +4168,7 @@ packages: '@smithy/util-middleware': 3.0.3 '@smithy/util-stream': 3.1.3 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-ssec@3.609.0: @@ -4174,7 +4177,7 @@ packages: dependencies: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/middleware-user-agent@3.645.0: @@ -4185,7 +4188,7 @@ packages: '@aws-sdk/util-endpoints': 3.645.0 '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/region-config-resolver@3.614.0: @@ -4197,7 +4200,7 @@ packages: '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 '@smithy/util-middleware': 3.0.3 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/s3-request-presigner@3.645.0: @@ -4262,7 +4265,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 '@smithy/util-endpoints': 2.0.5 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/util-format-url@3.609.0: @@ -4288,7 +4291,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/types': 3.3.0 bowser: 2.11.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/util-user-agent-node@3.614.0: @@ -4303,7 +4306,7 @@ packages: '@aws-sdk/types': 3.609.0 '@smithy/node-config-provider': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@aws-sdk/xml-builder@3.609.0: @@ -4311,7 +4314,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@babel/code-frame@7.24.7: @@ -9020,7 +9023,6 @@ packages: requiresBuild: true dependencies: tslib: 2.8.1 - dev: false optional: true /@emotion/hash@0.9.2: @@ -10643,7 +10645,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 - dev: false optional: true /@img/sharp-darwin-x64@0.33.5: @@ -10654,7 +10655,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.4 - dev: false optional: true /@img/sharp-libvips-darwin-arm64@1.0.4: @@ -10662,7 +10662,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-darwin-x64@1.0.4: @@ -10670,7 +10669,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linux-arm64@1.0.4: @@ -10678,7 +10676,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linux-arm@1.0.5: @@ -10686,7 +10683,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linux-s390x@1.0.4: @@ -10694,7 +10690,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linux-x64@1.0.4: @@ -10702,7 +10697,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linuxmusl-arm64@1.0.4: @@ -10710,7 +10704,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-libvips-linuxmusl-x64@1.0.4: @@ -10718,7 +10711,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@img/sharp-linux-arm64@0.33.5: @@ -10729,7 +10721,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 - dev: false optional: true /@img/sharp-linux-arm@0.33.5: @@ -10740,7 +10731,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.5 - dev: false optional: true /@img/sharp-linux-s390x@0.33.5: @@ -10751,7 +10741,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.0.4 - dev: false optional: true /@img/sharp-linux-x64@0.33.5: @@ -10762,7 +10751,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.4 - dev: false optional: true /@img/sharp-linuxmusl-arm64@0.33.5: @@ -10773,7 +10761,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - dev: false optional: true /@img/sharp-linuxmusl-x64@0.33.5: @@ -10784,7 +10771,6 @@ packages: requiresBuild: true optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - dev: false optional: true /@img/sharp-wasm32@0.33.5: @@ -10794,7 +10780,6 @@ packages: requiresBuild: true dependencies: '@emnapi/runtime': 1.2.0 - dev: false optional: true /@img/sharp-win32-ia32@0.33.5: @@ -10803,7 +10788,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@img/sharp-win32-x64@0.33.5: @@ -10812,7 +10796,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@isaacs/cliui@8.0.2: @@ -11043,7 +11026,6 @@ packages: /@next/env@15.1.2: resolution: {integrity: sha512-Hm3jIGsoUl6RLB1vzY+dZeqb+/kWPZ+h34yiWxW0dV87l8Im/eMOwpOA+a0L78U0HM04syEjXuRlCozqpwuojQ==} - dev: false /@next/eslint-plugin-next@15.0.4: resolution: {integrity: sha512-rbsF17XGzHtR7SDWzWpavSfum3/UdnF8bAaisnKwP//si3KWPTedVUsflAdjyK1zW3rweBjbALfKcavFneLGvg==} @@ -11066,7 +11048,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-darwin-x64@14.2.15: @@ -11084,7 +11065,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-gnu@14.2.15: @@ -11102,7 +11082,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-musl@14.2.15: @@ -11120,7 +11099,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-gnu@14.2.15: @@ -11138,7 +11116,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-musl@14.2.15: @@ -11156,7 +11133,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-win32-arm64-msvc@14.2.15: @@ -11174,7 +11150,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@next/swc-win32-ia32-msvc@14.2.15: @@ -11201,7 +11176,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: @@ -13356,7 +13330,7 @@ packages: '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 '@smithy/util-middleware': 3.0.3 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/core@2.4.0: @@ -13372,7 +13346,7 @@ packages: '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-middleware': 3.0.3 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/credential-provider-imds@3.2.0: @@ -13383,7 +13357,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/eventstream-codec@3.1.2: @@ -13401,7 +13375,7 @@ packages: dependencies: '@smithy/eventstream-serde-universal': 3.0.5 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/eventstream-serde-config-resolver@3.0.3: @@ -13409,7 +13383,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/eventstream-serde-node@3.0.5: @@ -13418,7 +13392,7 @@ packages: dependencies: '@smithy/eventstream-serde-universal': 3.0.5 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/eventstream-serde-universal@3.0.5: @@ -13437,7 +13411,7 @@ packages: '@smithy/querystring-builder': 3.0.3 '@smithy/types': 3.3.0 '@smithy/util-base64': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/hash-blob-browser@3.1.2: @@ -13446,7 +13420,7 @@ packages: '@smithy/chunked-blob-reader': 3.0.0 '@smithy/chunked-blob-reader-native': 3.0.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/hash-node@3.0.3: @@ -13456,7 +13430,7 @@ packages: '@smithy/types': 3.3.0 '@smithy/util-buffer-from': 3.0.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/hash-stream-node@3.1.2: @@ -13465,14 +13439,14 @@ packages: dependencies: '@smithy/types': 3.3.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/invalid-dependency@3.0.3: resolution: {integrity: sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/is-array-buffer@2.2.0: @@ -13494,7 +13468,7 @@ packages: dependencies: '@smithy/types': 3.3.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/middleware-content-length@3.0.5: @@ -13503,7 +13477,7 @@ packages: dependencies: '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/middleware-endpoint@3.1.0: @@ -13530,7 +13504,7 @@ packages: '@smithy/types': 3.3.0 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 - tslib: 2.6.2 + tslib: 2.8.1 uuid: 9.0.1 dev: false @@ -13539,7 +13513,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/middleware-stack@3.0.3: @@ -13547,7 +13521,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/node-config-provider@3.1.4: @@ -13557,7 +13531,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/node-http-handler@3.1.4: @@ -13568,7 +13542,7 @@ packages: '@smithy/protocol-http': 4.1.0 '@smithy/querystring-builder': 3.0.3 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/property-provider@3.1.3: @@ -13576,7 +13550,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/protocol-http@4.1.0: @@ -13657,7 +13631,7 @@ packages: dependencies: '@smithy/querystring-parser': 3.0.3 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-base64@3.0.0: @@ -13666,20 +13640,20 @@ packages: dependencies: '@smithy/util-buffer-from': 3.0.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-body-length-browser@3.0.0: resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} dependencies: - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-body-length-node@3.0.0: resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} engines: {node: '>=16.0.0'} dependencies: - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-buffer-from@2.2.0: @@ -13713,7 +13687,7 @@ packages: '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 bowser: 2.11.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-defaults-mode-node@3.0.15: @@ -13726,7 +13700,7 @@ packages: '@smithy/property-provider': 3.1.3 '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-endpoints@2.0.5: @@ -13735,7 +13709,7 @@ packages: dependencies: '@smithy/node-config-provider': 3.1.4 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-hex-encoding@3.0.0: @@ -13750,7 +13724,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-retry@3.0.3: @@ -13759,7 +13733,7 @@ packages: dependencies: '@smithy/service-error-classification': 3.0.3 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-stream@3.1.3: @@ -13773,7 +13747,7 @@ packages: '@smithy/util-buffer-from': 3.0.0 '@smithy/util-hex-encoding': 3.0.0 '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-uri-escape@3.0.0: @@ -13796,7 +13770,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@smithy/util-buffer-from': 3.0.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@smithy/util-waiter@3.1.2: @@ -13805,7 +13779,7 @@ packages: dependencies: '@smithy/abort-controller': 3.1.1 '@smithy/types': 3.3.0 - tslib: 2.6.2 + tslib: 2.8.1 dev: false /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.2): @@ -14185,13 +14159,11 @@ packages: /@swc/counter@0.1.3: resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - dev: false /@swc/helpers@0.5.15: resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} dependencies: tslib: 2.8.1 - dev: false /@swc/helpers@0.5.5: resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} @@ -17010,7 +16982,6 @@ packages: engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 - dev: false /bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} @@ -17302,7 +17273,6 @@ packages: /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - dev: false /clipboard@2.0.8: resolution: {integrity: sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==} @@ -24319,7 +24289,6 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: false /nlcst-to-string@4.0.0: resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} @@ -26240,7 +26209,6 @@ packages: nanoid: 3.3.7 picocolors: 1.1.1 source-map-js: 1.2.1 - dev: false /postcss@8.4.33: resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} @@ -28115,7 +28083,6 @@ packages: '@img/sharp-wasm32': 0.33.5 '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 - dev: false optional: true /shebang-command@2.0.0: @@ -28439,7 +28406,6 @@ packages: /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - dev: false /streamx@2.20.0: resolution: {integrity: sha512-ZGd1LhDeGFucr1CUCTBOS58ZhEendd0ttpGT3usTvosS4ntIwKN9LJFp+OeCSprsCPL14BXVRZlHGRY1V9PVzQ==} @@ -28683,7 +28649,6 @@ packages: '@babel/core': 7.23.2 client-only: 0.0.1 react: 19.0.0 - dev: false /stylehacks@6.1.1(postcss@8.4.47): resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} @@ -29346,7 +29311,6 @@ packages: /tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - dev: false /tsutils@3.21.0(typescript@5.5.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}