diff --git a/examples/v0.71.19/package.json b/examples/v0.71.19/package.json index d868f664..3284293b 100644 --- a/examples/v0.71.19/package.json +++ b/examples/v0.71.19/package.json @@ -18,6 +18,7 @@ "@babel/core": "^7.26.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", + "@hot-updater/aws": "0.12.0", "@hot-updater/metro": "0.12.0", "@hot-updater/supabase": "0.12.0", "@react-native-community/cli-platform-android": "10.2.0", diff --git a/packages/hot-updater/package.json b/packages/hot-updater/package.json index fe582e42..29139ddc 100644 --- a/packages/hot-updater/package.json +++ b/packages/hot-updater/package.json @@ -74,6 +74,7 @@ "@types/semver": "^7.5.8", "boxen": "^8.0.1", "dayjs": "^1.11.13", + "es-toolkit": "^1.32.0", "execa": "^9.5.2", "is-port-reachable": "^4.0.0", "jszip": "^3.10.1", @@ -85,6 +86,7 @@ "uuidv7": "^1.0.2" }, "peerDependencies": { + "@hot-updater/aws": "*", "@hot-updater/cloudflare": "*", "@hot-updater/supabase": "*" }, @@ -94,6 +96,9 @@ }, "@hot-updater/cloudflare": { "optional": true + }, + "@hot-updater/aws": { + "optional": true } } } diff --git a/packages/hot-updater/src/commands/deploy.ts b/packages/hot-updater/src/commands/deploy.ts index 29146aeb..e46b0391 100644 --- a/packages/hot-updater/src/commands/deploy.ts +++ b/packages/hot-updater/src/commands/deploy.ts @@ -126,10 +126,14 @@ export const deploy = async (options: DeployOptions) => { taskRef.buildResult = await buildPlugin.build({ platform: platform, }); - await createZip(taskRef.buildResult.buildPath, "bundle.zip"); + bundlePath = path.join(getCwd(), "bundle.zip"); + + await createZip({ + outfile: bundlePath, + targetDir: taskRef.buildResult.buildPath, + }); bundleId = taskRef.buildResult.bundleId; - bundlePath = path.join(getCwd(), "bundle.zip"); fileHash = await getFileHashFromFile(bundlePath); return `✅ Build Complete (${buildPlugin.name})`; diff --git a/packages/hot-updater/src/commands/init.ts b/packages/hot-updater/src/commands/init.ts index d21e1407..d3c17871 100644 --- a/packages/hot-updater/src/commands/init.ts +++ b/packages/hot-updater/src/commands/init.ts @@ -1,6 +1,7 @@ import { printBanner } from "@/components/banner"; import { ensureInstallPackages } from "@/utils/ensureInstallPackages"; import { isCancel, select } from "@clack/prompts"; +import { initAwsS3LambdaEdge } from "./init/aws"; import { initCloudflareD1R2Worker } from "./init/cloudflareD1R2Worker"; import { initSupabase } from "./init/supabase"; @@ -52,6 +53,7 @@ export const init = async () => { value: "cloudflare-d1-r2-worker", label: "Cloudflare D1 + R2 + Worker", }, + { value: "aws", label: "AWS S3 + Lambda@Edge" }, ], }); @@ -81,6 +83,10 @@ export const init = async () => { await initCloudflareD1R2Worker(); break; } + case "aws": { + await initAwsS3LambdaEdge(); + break; + } default: throw new Error("Invalid provider"); } diff --git a/packages/hot-updater/src/commands/init/aws/index.ts b/packages/hot-updater/src/commands/init/aws/index.ts new file mode 100644 index 00000000..6812c069 --- /dev/null +++ b/packages/hot-updater/src/commands/init/aws/index.ts @@ -0,0 +1,914 @@ +import path from "path"; +import { link } from "@/components/banner"; +import { transformTemplate } from "@/utils/transformTemplate"; +import * as p from "@clack/prompts"; +import type { + BucketLocationConstraint, + DistributionConfig, +} from "@hot-updater/aws/sdk"; +import { getCwd } from "@hot-updater/plugin-core"; +import dayjs from "dayjs"; +import { merge } from "es-toolkit"; +import fs from "fs/promises"; +import { regionLocationMap } from "./regionLocationMap"; + +import { createZip } from "@/utils/createZip"; +import { delay } from "@/utils/delay"; +import { makeEnv } from "@/utils/makeEnv"; +import { ExecaError, execa } from "execa"; +import picocolors from "picocolors"; + +// Template file: hot-updater.config.ts +const CONFIG_TEMPLATE_WITH_SESSION = ` +import { metro } from "@hot-updater/metro"; +import { s3Storage, s3Database } from "@hot-updater/aws"; +import { defineConfig } from "hot-updater"; +import "dotenv/config"; + +const options = { + bucketName: process.env.HOT_UPDATER_S3_BUCKET_NAME!, + region: process.env.HOT_UPDATER_S3_REGION!, + credentials: { + accessKeyId: process.env.HOT_UPDATER_S3_ACCESS_KEY_ID!, + secretAccessKey: process.env.HOT_UPDATER_S3_SECRET_ACCESS_KEY!, + // This token may expire. For permanent use, it's recommended to get a key with S3FullAccess permission and remove this field. + sessionToken: process.env.HOT_UPDATER_S3_SESSION_TOKEN!, + }, +}; + +export default defineConfig({ + build: metro({ enableHermes: true }), + storage: s3Storage(options), + database: s3Database(options), +}); +`; + +const CONFIG_TEMPLATE = ` +import { metro } from "@hot-updater/metro"; +import { s3Storage, s3Database } from "@hot-updater/aws"; +import { defineConfig } from "hot-updater"; +import "dotenv/config"; + +const options = { + bucketName: process.env.HOT_UPDATER_S3_BUCKET_NAME!, + region: process.env.HOT_UPDATER_S3_REGION!, + credentials: { + accessKeyId: process.env.HOT_UPDATER_S3_ACCESS_KEY_ID!, + secretAccessKey: process.env.HOT_UPDATER_S3_SECRET_ACCESS_KEY!, + }, +}; + +export default defineConfig({ + build: metro({ enableHermes: true }), + storage: s3Storage(options), + database: s3Database(options), +}); +`; + +// Template file: Example code to add to App.tsx +const SOURCE_TEMPLATE = `// add this to your App.tsx +import { HotUpdater } from "@hot-updater/react-native"; + +function App() { + return ... +} + +export default HotUpdater.wrap({ + source: "%%source%%", +})(App);`; + +const checkIfAwsCliInstalled = async () => { + try { + await execa("aws", ["--version"]); + return true; + } catch (error) { + return false; + } +}; + +export async function createOrSelectIamRole({ + region, + credentials, +}: { + region: BucketLocationConstraint; + credentials: { + accessKeyId: string; + secretAccessKey: string; + }; +}): Promise { + const { SDK } = await import("@hot-updater/aws/sdk"); + const iamClient = new SDK.IAM.IAM({ region, credentials }); + + // Set trust policy for Lambda@Edge + const assumeRolePolicyDocument = JSON.stringify({ + Version: "2012-10-17", + Statement: [ + { + Effect: "Allow", + Principal: { + Service: ["lambda.amazonaws.com", "edgelambda.amazonaws.com"], + }, + Action: "sts:AssumeRole", + }, + ], + }); + + const roleName = "hot-updater-edge-role"; + + try { + // Check if role already exists + const { Role: existingRole } = await iamClient.getRole({ + RoleName: roleName, + }); + + if (existingRole?.Arn) { + p.log.info(`Using existing IAM role: ${roleName} (${existingRole.Arn})`); + return existingRole.Arn; + } + } catch (error) { + // Role doesn't exist, create new one + try { + const createRoleResp = await iamClient.createRole({ + RoleName: roleName, + AssumeRolePolicyDocument: assumeRolePolicyDocument, + Description: "Role for Lambda@Edge to access S3", + }); + + const lambdaRoleArn = createRoleResp.Role?.Arn!; + p.log.info(`Created IAM role: ${roleName} (${lambdaRoleArn})`); + + // Attach required policies + await iamClient.attachRolePolicy({ + RoleName: roleName, + PolicyArn: + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + }); + await iamClient.attachRolePolicy({ + RoleName: roleName, + PolicyArn: "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess", + }); + p.log.info( + `Attached AWSLambdaBasicExecutionRole and AmazonS3ReadOnlyAccess policies to ${roleName}`, + ); + + return lambdaRoleArn; + } catch (createError) { + if (createError instanceof Error) { + p.log.error( + `Error setting up IAM role for Lambda@Edge: ${createError.message}`, + ); + } + process.exit(1); + } + } + throw new Error("Failed to create or get IAM role"); +} + +/** + * Deploy Lambda@Edge function + * - Zip the local ./lambda folder, create a function in us-east-1 region, + * - Publish a new version of the function + */ +export const deployLambdaEdge = async ( + credentials: + | { + accessKeyId: string; + secretAccessKey: string; + } + | undefined, + lambdaRoleArn: string, +): Promise<{ + lambdaName: string; + functionArn: string; +}> => { + const { SDK } = await import("@hot-updater/aws/sdk"); + const cwd = getCwd(); + + // 1. Lambda function name + const lambdaName = await p.text({ + message: "Enter the name of the Lambda@Edge function", + defaultValue: "hot-updater-edge", + placeholder: "hot-updater-edge", + }); + if (p.isCancel(lambdaName)) process.exit(1); + + // 2. Create zip file + const lambdaPath = require.resolve("@hot-updater/aws/lambda"); + const lambdaDir = path.dirname(lambdaPath); + + // 3. Lambda client + const lambdaClient = new SDK.Lambda.Lambda({ + region: "us-east-1", + credentials, + }); + + const functionArn: { + arn: string | null; + version: string | null; + } = { + arn: null, + version: null, + }; + + const zipFilePath = path.join(cwd, `${lambdaName}.zip`); + // 4. Show step-by-step indicators using p.tasks + await p.tasks([ + { + title: "Compressing Lambda code to zip", + task: async () => { + try { + await createZip({ + outfile: zipFilePath, + targetDir: lambdaDir, + }); + return "Compressed Lambda code to zip"; + } catch (error) { + throw new Error( + "Failed to create zip archive of Lambda function code", + ); + } + }, + }, + { + title: "Creating or Updating Lambda function", + task: async (message) => { + try { + // Create new function + const createResp = await lambdaClient.createFunction({ + FunctionName: lambdaName, + Runtime: "nodejs22.x", + Role: lambdaRoleArn, + Handler: "index.handler", + Code: { ZipFile: await fs.readFile(zipFilePath) }, + Description: "Hot Updater Lambda@Edge function", + Publish: true, + }); + + functionArn.arn = createResp.FunctionArn || null; + functionArn.version = createResp.Version || "1"; + return `Created Lambda "${lambdaName}" function`; + } catch (error) { + // Update if function already exists + if ( + error instanceof Error && + error.name === "ResourceConflictException" + ) { + message( + `Function "${lambdaName}" already exists. Updating function code...`, + ); + + const updateResp = await lambdaClient.updateFunctionCode({ + FunctionName: lambdaName, + ZipFile: await fs.readFile(zipFilePath), + Publish: true, + }); + void fs.rm(zipFilePath, { force: true }); + functionArn.arn = updateResp.FunctionArn || null; + functionArn.version = updateResp.Version || "1"; + } else { + // Pass through other errors + if (error instanceof Error) { + p.log.error( + `Failed to create or update Lambda function: ${error.message}`, + ); + } + throw error; + } + return `Updated Lambda "${lambdaName}" function`; + } + }, + }, + { + title: "Waiting for Lambda function to become Active", + task: async () => { + // Lambda ARN should be "unqualified ARN" + :version + // ex) "arn:aws:lambda:us-east-1:123456789012:function:hot-updater-edge:2" + const qualifiedName = `${lambdaName}:${functionArn.version}`; + + // Check repeatedly until state becomes Active + while (true) { + const resp = await lambdaClient.getFunctionConfiguration({ + FunctionName: qualifiedName, + }); + if (resp.State === "Active") { + return "Lambda function is now active"; + } + + if (resp.State === "Failed") { + // Stop deployment if Lambda is in Failed state + throw new Error( + `Lambda function is in a Failed state. Reason: ${resp.StateReason}`, + ); + } + + // Wait before retrying + await new Promise((r) => setTimeout(r, 2000)); + } + }, + }, + ]); + + if (!functionArn.arn || !functionArn.version) { + throw new Error("Failed to create or update Lambda function"); + } + + // 5. Set Qualified ARN for Lambda@Edge + // (In case version is not automatically appended from createFunction result) + if (!functionArn.arn.includes(`:${functionArn.version}`)) { + functionArn.arn = `${functionArn.arn}:${functionArn.version}`; + } + p.log.info(`Using Lambda ARN: ${functionArn.arn}`); + + return { lambdaName, functionArn: functionArn.arn }; +}; + +export const createCloudFrontDistribution = async ( + credentials: + | { + accessKeyId: string; + secretAccessKey: string; + } + | undefined, + region: string, + bucketName: string, + functionArn: string, +): Promise<{ + distributionId: string; + distributionDomain: string; +}> => { + const { SDK } = await import("@hot-updater/aws/sdk"); + const Cloudfront = SDK.CloudFront.CloudFront; + const cloudfrontClient = new Cloudfront({ region, credentials }); + + const bucketDomain = `${bucketName}.s3.${region}.amazonaws.com`; + + const matchingDistributions: Array<{ Id: string; DomainName: string }> = []; + try { + const listResp = await cloudfrontClient.listDistributions({}); + const items = listResp.DistributionList?.Items || []; + for (const dist of items) { + const origins = dist.Origins?.Items || []; + if (origins.some((origin) => origin.DomainName === bucketDomain)) { + matchingDistributions.push({ + Id: dist.Id!, + DomainName: dist.DomainName!, + }); + } + } + } catch (error) { + console.error("Error listing CloudFront distributions:", error); + } + + let selectedDistribution: { Id: string; DomainName: string } | null = null; + if (matchingDistributions.length === 1) { + selectedDistribution = matchingDistributions[0] ?? null; + } else if (matchingDistributions.length > 1) { + const selectedDistributionStr = await p.select({ + message: + "Multiple CloudFront distributions found. Please select one to use:", + options: matchingDistributions.map((dist) => ({ + value: JSON.stringify(dist), + label: `${dist.Id} (${dist.DomainName})`, + })), + }); + if (p.isCancel(selectedDistributionStr)) { + process.exit(0); + } + selectedDistribution = JSON.parse(selectedDistributionStr); + } + // Apply newly deployed Lambda ARN + if (selectedDistribution) { + p.log.success( + `Existing CloudFront distribution selected. Distribution ID: ${selectedDistribution.Id}.`, + ); + try { + const { DistributionConfig, ETag } = + await cloudfrontClient.getDistributionConfig({ + Id: selectedDistribution.Id, + }); + let updateRequired = false; + let hasOriginRequest = false; + if (!DistributionConfig) { + throw new Error("Distribution config is missing"); + } + + let distributionConfig: DistributionConfig = DistributionConfig; + if (!DistributionConfig?.DefaultCacheBehavior) { + throw new Error("Distribution config or default behavior is missing"); + } + + const defaultBehavior = distributionConfig.DefaultCacheBehavior; + const lambdaAssociations = + defaultBehavior?.LambdaFunctionAssociations ?? { + Quantity: 0, + Items: [], + }; + + if ((lambdaAssociations.Quantity ?? 0) > 0 && lambdaAssociations.Items) { + for (const [index, assoc] of lambdaAssociations.Items.entries()) { + if (assoc.EventType === "origin-request") { + hasOriginRequest = true; + if ( + assoc.LambdaFunctionARN !== functionArn && + lambdaAssociations.Items[index] + ) { + p.log.info( + `Updating Lambda association from ${assoc.LambdaFunctionARN} to ${functionArn}`, + ); + distributionConfig = merge(distributionConfig, { + DefaultCacheBehavior: { + LambdaFunctionAssociations: { + Items: [ + { + EventType: "origin-request", + LambdaFunctionARN: functionArn, + }, + ], + Quantity: 1, + }, + }, + }); + updateRequired = true; + } + } + } + } + + if (!hasOriginRequest) { + updateRequired = true; + if (!defaultBehavior?.LambdaFunctionAssociations) { + distributionConfig = merge(distributionConfig, { + DefaultCacheBehavior: { + LambdaFunctionAssociations: { + Quantity: 0, + Items: [], + }, + }, + }); + } + + distributionConfig = merge(distributionConfig, { + DefaultCacheBehavior: { + LambdaFunctionAssociations: { + Items: [ + { + EventType: "origin-request", + LambdaFunctionARN: functionArn, + }, + ], + Quantity: 1, + }, + }, + }); + } + + if (updateRequired) { + distributionConfig = merge(distributionConfig, { + CacheBehaviors: { + Quantity: 1, + Items: [ + { + PathPattern: "/api/*", + TargetOriginId: bucketName, + ViewerProtocolPolicy: "redirect-to-https", + LambdaFunctionAssociations: { + Quantity: 1, + Items: [ + { + EventType: "origin-request", + LambdaFunctionARN: functionArn, + }, + ], + }, + MinTTL: 0, + DefaultTTL: 0, + MaxTTL: 0, + Compress: true, + SmoothStreaming: false, + FieldLevelEncryptionId: "", + AllowedMethods: { + Quantity: 3, + Items: ["GET", "HEAD", "OPTIONS"], + CachedMethods: { + Quantity: 2, + Items: ["GET", "HEAD"], + }, + }, + ForwardedValues: { + QueryString: false, + Cookies: { Forward: "none" }, + Headers: { + Quantity: 3, + Items: ["x-bundle-id", "x-app-version", "x-app-platform"], + }, + QueryStringCacheKeys: { + Quantity: 0, + Items: [], + }, + }, + }, + ], + }, + }); + + await cloudfrontClient.updateDistribution({ + Id: selectedDistribution.Id, + IfMatch: ETag, + DistributionConfig: distributionConfig, + }); + p.log.success( + "CloudFront distribution updated with new Lambda function ARN.", + ); + } else { + p.log.info( + "CloudFront distribution already has the correct Lambda function association.", + ); + } + await cloudfrontClient.createInvalidation({ + DistributionId: selectedDistribution.Id, + InvalidationBatch: { + CallerReference: dayjs().format(), + Paths: { + Quantity: 1, + Items: ["/*"], + }, + }, + }); + p.log.success("Cache invalidation request completed."); + return { + distributionId: selectedDistribution.Id, + distributionDomain: selectedDistribution.DomainName, + }; + } catch (err) { + p.log.error( + `Failed to update CloudFront distribution: ${ + err instanceof Error ? err.message : String(err) + }`, + ); + throw err; + } + } + + const distributionConfig: DistributionConfig = { + CallerReference: dayjs().format(), + Comment: "Hot Updater CloudFront distribution", + Enabled: true, + Origins: { + Quantity: 1, + Items: [ + { + Id: bucketName, + DomainName: bucketDomain, + S3OriginConfig: { OriginAccessIdentity: "" }, + }, + ], + }, + DefaultCacheBehavior: { + TargetOriginId: bucketName, + ViewerProtocolPolicy: "redirect-to-https", + LambdaFunctionAssociations: { + Quantity: 1, + Items: [ + { + EventType: "origin-request", + LambdaFunctionARN: functionArn, + }, + ], + }, + ForwardedValues: { + QueryString: false, + Cookies: { Forward: "none" }, + }, + MinTTL: 0, + }, + CacheBehaviors: { + Quantity: 1, + Items: [ + { + PathPattern: "/api/*", + TargetOriginId: bucketName, + ViewerProtocolPolicy: "redirect-to-https", + LambdaFunctionAssociations: { + Quantity: 1, + Items: [ + { + EventType: "origin-request", + LambdaFunctionARN: functionArn, + }, + ], + }, + MinTTL: 0, + DefaultTTL: 0, + MaxTTL: 0, + ForwardedValues: { + QueryString: false, + Cookies: { Forward: "none" }, + Headers: { + Quantity: 3, + Items: ["x-bundle-id", "x-app-version", "x-app-platform"], + }, + }, + }, + ], + }, + DefaultRootObject: "index.html", + ViewerCertificate: { CloudFrontDefaultCertificate: true }, + Restrictions: { + GeoRestriction: { + RestrictionType: "none", + Quantity: 0, + }, + }, + }; + + try { + const distResp = await cloudfrontClient.createDistribution({ + DistributionConfig: distributionConfig, + }); + const distributionId = distResp.Distribution?.Id!; + const distributionDomain = distResp.Distribution?.DomainName!; + p.log.success( + `Created new CloudFront distribution. Distribution ID: ${distributionId}`, + ); + let retryCount = 0; + await p.tasks([ + { + title: "Waiting for CloudFront distribution to complete...", + task: async (message) => { + while (retryCount < 60 * 10) { + try { + const status = await cloudfrontClient.getDistribution({ + Id: distributionId, + }); + if (status.Distribution?.Status === "Deployed") { + return "CloudFront distribution deployment completed."; + } + throw new Error("Retry"); + } catch (err) { + if (retryCount++ >= 5) { + message( + `CloudFront distribution is still in progress. This may take few minutes. (${retryCount})`, + ); + } + await delay(1000); + } + } + p.log.error("CloudFront distribution deployment timed out."); + process.exit(1); + }, + }, + ]); + return { distributionId, distributionDomain }; + } catch (error) { + p.log.error( + `CloudFront distribution creation failed: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + throw error; + } +}; + +export const initAwsS3LambdaEdge = async () => { + const { SDK } = await import("@hot-updater/aws/sdk"); + + const isAwsCliInstalled = await checkIfAwsCliInstalled(); + if (!isAwsCliInstalled) { + p.log.error( + `AWS CLI is not installed. Please visit ${link("https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html")} for installation instructions`, + ); + process.exit(1); + } + + let credentials: + | { + accessKeyId: string; + secretAccessKey: string; + sessionToken?: string; + } + | undefined = undefined; + + const mode = await p.select({ + message: "Select the mode to login to AWS", + options: [ + { + label: "AWS Access Key ID & Secret Access Key (Recommend)", + value: "account", + }, + { label: "AWS SSO Login", value: "sso" }, + ], + }); + if (p.isCancel(mode)) process.exit(1); + + p.log.message(picocolors.blue("The following permissions are required:")); + p.log.message( + `${picocolors.blue("AmazonS3FullAccess")}: Create and read S3 buckets`, + ); + p.log.message( + `${picocolors.blue("AWSLambda_FullAccess")}: Create and update Lambda functions`, + ); + p.log.message( + `${picocolors.blue("CloudFrontFullAccess")}: Create and update CloudFront distributions`, + ); + p.log.message( + `${picocolors.blue("IAMFullAccess")}: Get or create IAM roles for Lambda@Edge`, + ); + + if (mode === "sso") { + try { + const profile = await p.text({ + message: "Enter the SSO profile name", + defaultValue: "default", + placeholder: "default", + }); + if (p.isCancel(profile)) { + process.exit(1); + } + + await execa("aws", ["sso", "login", "--profile", profile], { + stdio: "inherit", + }); + + credentials = await SDK.CredentialsProvider.fromSSO({ + profile, + })(); + } catch (error) { + if (error instanceof ExecaError) { + p.log.error(error.stdout || error.stderr || error.message); + } + process.exit(1); + } + } else { + credentials = await p.group({ + accessKeyId: () => + p.text({ + message: "Enter your AWS Access Key ID", + validate: (value) => { + if (!value) { + return "Access Key ID is required"; + } + return; + }, + }), + secretAccessKey: () => + p.text({ + message: "Enter your AWS Secret Access Key", + validate: (value) => { + if (!value) { + return "Secret Access Key is required"; + } + + return; + }, + }), + }); + + if (p.isCancel(credentials)) process.exit(1); + + credentials = { + accessKeyId: credentials.accessKeyId, + secretAccessKey: credentials.secretAccessKey, + }; + } + + // Enter region for AWS S3 bucket creation + const $region = await p.select({ + message: "Enter AWS region for the S3 bucket", + options: Object.values(SDK.S3.BucketLocationConstraint).map((r) => ({ + label: `${r} (${regionLocationMap[r]})` as string, + value: r as string, + })), + }); + if (p.isCancel($region)) process.exit(1); + + const region = $region as BucketLocationConstraint; + // Create S3 client + const S3 = SDK.S3.S3; + const s3Client = new S3({ region, credentials }); + const availableBuckets: { name: string }[] = []; + try { + await p.tasks([ + { + title: "Checking S3 Buckets...", + task: async () => { + const buckets = await s3Client.listBuckets({}); + availableBuckets.push( + ...(buckets.Buckets ?? []) + .filter((bucket) => bucket.Name) + .map((bucket) => ({ + name: bucket.Name!, + })), + ); + }, + }, + ]); + } catch (e) { + if (e instanceof Error) { + p.log.error(e.message); + } + throw e; + } + + const createKey = `create/${Math.random().toString(36).substring(2, 15)}`; + + let bucketName = await p.select({ + message: "S3 Bucket List", + options: [ + ...availableBuckets.map((bucket) => ({ + value: bucket.name, + label: bucket.name, + })), + { + value: createKey, + label: "Create New S3 Bucket", + }, + ], + }); + + if (p.isCancel(bucketName)) { + process.exit(1); + } + + if (bucketName === createKey) { + const name = await p.text({ + message: "Enter the name of the new S3 Bucket", + defaultValue: "hot-updater-storage", + placeholder: "hot-updater-storage", + }); + if (p.isCancel(name)) { + process.exit(1); + } + bucketName = name; + + try { + await s3Client.createBucket({ + Bucket: name, + CreateBucketConfiguration: { + LocationConstraint: region, + }, + }); + p.log.info(`Created S3 bucket: ${bucketName}`); + } catch (error) { + if (error instanceof Error) { + p.log.error(`Failed to create S3 bucket: ${error.message}`); + } + throw error; + } + } + p.log.info(`Selected S3 Bucket: ${bucketName}`); + + const lambdaRoleArn = await createOrSelectIamRole({ region, credentials }); + + // Deploy Lambda@Edge function (us-east-1) + const { functionArn } = await deployLambdaEdge(credentials, lambdaRoleArn); + + // Create CloudFront distribution + const { distributionDomain } = await createCloudFrontDistribution( + credentials, + region, + bucketName, + functionArn, + ); + + // Create config file and environment variable file + if (mode === "sso") { + await fs.writeFile("hot-updater.config.ts", CONFIG_TEMPLATE_WITH_SESSION); + } else { + await fs.writeFile("hot-updater.config.ts", CONFIG_TEMPLATE); + } + + const comment = + mode === "account" + ? "The current key may have excessive permissions. Update it with an S3FullAccess-only key." + : "This key was generated via SSO login and may expire. Update it with an S3FullAccess-only key."; + await makeEnv({ + HOT_UPDATER_S3_BUCKET_NAME: bucketName, + HOT_UPDATER_S3_REGION: region, + HOT_UPDATER_S3_ACCESS_KEY_ID: { + comment, + value: credentials?.accessKeyId ?? "", + }, + HOT_UPDATER_S3_SECRET_ACCESS_KEY: { + comment, + value: credentials?.secretAccessKey ?? "", + }, + ...(mode === "sso" && { + HOT_UPDATER_S3_SESSION_TOKEN: credentials.sessionToken, + }), + }); + p.log.success("Generated '.env' file with AWS settings."); + p.log.success("Generated 'hot-updater.config.ts' file with AWS settings."); + + // Provide API URL to client side using CloudFront domain + const sourceUrl = `https://${distributionDomain}/api/check-update`; + p.note( + transformTemplate(SOURCE_TEMPLATE, { + source: sourceUrl, + }), + ); + + p.log.message( + `Next step: ${link("https://gronxb.github.io/hot-updater/guide/providers/3_aws-s3-lambda-edge.html")}`, + ); + p.log.success("Done! 🎉"); +}; diff --git a/packages/hot-updater/src/commands/init/aws/regionLocationMap.ts b/packages/hot-updater/src/commands/init/aws/regionLocationMap.ts new file mode 100644 index 00000000..7d1a3ef5 --- /dev/null +++ b/packages/hot-updater/src/commands/init/aws/regionLocationMap.ts @@ -0,0 +1,32 @@ +import type { BucketLocationConstraint } from "@hot-updater/aws/sdk"; + +export const regionLocationMap: Record = { + EU: "Europe", + "af-south-1": "Cape Town, South Africa", + "ap-east-1": "Hong Kong", + "ap-northeast-1": "Tokyo, Japan", + "ap-northeast-2": "Seoul, South Korea", + "ap-northeast-3": "Osaka, Japan", + "ap-south-1": "Mumbai, India", + "ap-south-2": "Hyderabad, India", + "ap-southeast-1": "Singapore", + "ap-southeast-2": "Sydney, Australia", + "ap-southeast-3": "Jakarta, Indonesia", + "ca-central-1": "Montreal, Canada", + "cn-north-1": "Beijing, China", + "cn-northwest-1": "Ningxia, China", + "eu-central-1": "Frankfurt, Germany", + "eu-north-1": "Stockholm, Sweden", + "eu-south-1": "Milan, Italy", + "eu-south-2": "Spain", + "eu-west-1": "Ireland", + "eu-west-2": "London, UK", + "eu-west-3": "Paris, France", + "me-south-1": "Bahrain", + "sa-east-1": "São Paulo, Brazil", + "us-east-2": "Ohio, USA", + "us-gov-east-1": "US Gov East (Virginia, USA)", + "us-gov-west-1": "US Gov West (Oregon, USA)", + "us-west-1": "California, USA", + "us-west-2": "Oregon, USA", +}; diff --git a/packages/hot-updater/src/utils/createZip.ts b/packages/hot-updater/src/utils/createZip.ts index 4de081d5..e6ef4386 100644 --- a/packages/hot-updater/src/utils/createZip.ts +++ b/packages/hot-updater/src/utils/createZip.ts @@ -3,9 +3,15 @@ import fs from "fs/promises"; import JSZip from "jszip"; -export const createZip = async (dirPath: string, filename: string) => { +export const createZip = async ({ + outfile, + targetDir, +}: { + targetDir: string; + outfile: string; +}) => { const zip = new JSZip(); - await fs.rm(path.join(dirPath, filename), { force: true }); + await fs.rm(outfile, { force: true }); async function addFiles(dir: string, zipFolder: JSZip) { const files = await fs.readdir(dir); @@ -29,7 +35,7 @@ export const createZip = async (dirPath: string, filename: string) => { } } - await addFiles(dirPath, zip); + await addFiles(targetDir, zip); // fix hash zip.forEach((_, file) => { @@ -45,5 +51,6 @@ export const createZip = async (dirPath: string, filename: string) => { platform: "UNIX", }); - await fs.writeFile(filename, content); + await fs.writeFile(outfile, content); + return outfile; }; diff --git a/packages/hot-updater/src/utils/makeEnv.spec.ts b/packages/hot-updater/src/utils/makeEnv.spec.ts index f4e3b4e2..0804151f 100644 --- a/packages/hot-updater/src/utils/makeEnv.spec.ts +++ b/packages/hot-updater/src/utils/makeEnv.spec.ts @@ -15,7 +15,6 @@ describe("makeEnv", () => { it("adds new environment variables while preserving existing .env content", async () => { vi.mocked(fs.readFile).mockResolvedValueOnce("EXISTING_KEY=existing_value"); - const newEnvVars = { NEW_KEY: "new_value", }; @@ -25,9 +24,8 @@ describe("makeEnv", () => { expect(result).toBe("EXISTING_KEY=existing_value\nNEW_KEY=new_value"); }); - it("overwrites environment variables with the same key", async () => { + it("overwrites environment variables with the same key (string value)", async () => { vi.mocked(fs.readFile).mockResolvedValueOnce("TEST_KEY=old_value"); - const newEnvVars = { TEST_KEY: "new_value", }; @@ -41,7 +39,6 @@ describe("makeEnv", () => { vi.mocked(fs.readFile).mockResolvedValueOnce( "EXISTING_KEY=existing_value\nNEW_KEY=old_value", ); - const newEnvVars = { NEW_KEY: "new_value", }; @@ -50,11 +47,10 @@ describe("makeEnv", () => { expect(result).toBe("EXISTING_KEY=existing_value\nNEW_KEY=new_value"); }); - it("preserves keys that don't exist in the new environment variables", async () => { + it("preserves existing comments and adds new keys at the end", async () => { vi.mocked(fs.readFile).mockResolvedValueOnce( "# Key\nEXISTING_KEY=existing_value\n\nNEW_KEY=old_value", ); - const newEnvVars = { NEW_KEY: "new_value", NEW_KEY2: "new_value2", @@ -65,4 +61,35 @@ describe("makeEnv", () => { "# Key\nEXISTING_KEY=existing_value\n\nNEW_KEY=new_value\nNEW_KEY2=new_value2", ); }); + + it("adds new environment variable with comment object when file is empty", async () => { + vi.mocked(fs.readFile).mockResolvedValueOnce(""); + const newEnvVars = { + HI: { comment: "This Test Env", value: "ASD" }, + }; + + const result = await makeEnv(newEnvVars); + expect(result).toBe("# This Test Env\nHI=ASD"); + }); + + it("overwrites existing environment variable with comment object", async () => { + vi.mocked(fs.readFile).mockResolvedValueOnce("HI=old_value"); + const newEnvVars = { + HI: { comment: "Updated Comment", value: "ASD" }, + }; + + const result = await makeEnv(newEnvVars); + expect(result).toBe("# Updated Comment\nHI=ASD"); + }); + + it("mixes string and object values", async () => { + vi.mocked(fs.readFile).mockResolvedValueOnce("A=1\nB=2"); + const newEnvVars = { + A: { comment: "A comment", value: "100" }, + C: "3", + }; + + const result = await makeEnv(newEnvVars); + expect(result).toBe("# A comment\nA=100\nB=2\nC=3"); + }); }); diff --git a/packages/hot-updater/src/utils/makeEnv.ts b/packages/hot-updater/src/utils/makeEnv.ts index 57ea4285..b201f89e 100644 --- a/packages/hot-updater/src/utils/makeEnv.ts +++ b/packages/hot-updater/src/utils/makeEnv.ts @@ -1,50 +1,87 @@ import fs from "fs/promises"; +type EnvVarValue = string | { comment: string; value: string }; + export const makeEnv = async ( - newEnvVars: Record, + newEnvVars: Record, filePath = ".env", ): Promise => { try { - // Read the existing .env file or initialize with an empty string + // Read the existing .env file or initialize with an empty string if not found const existingContent = await fs .readFile(filePath, "utf-8") .catch(() => ""); - - // Parse the existing content while preserving comments and formatting - const lines = existingContent.split("\n"); - const envVars = new Map(); + // If file is empty, use an empty array to avoid an initial empty line. + const lines = existingContent ? existingContent.split("\n") : []; + const processedKeys = new Set(); const updatedLines: string[] = []; - for (const line of lines) { + for (let i = 0; i < lines.length; i++) { + const line = lines[i] ?? ""; const trimmedLine = line.trim(); - if (!trimmedLine || trimmedLine.startsWith("#")) { - // Preserve empty lines and comments + // Handle empty lines: preserve them as-is. + if (trimmedLine === "") { updatedLines.push(line); - } else { - const [key, ...rest] = line.split("="); - const value = rest.join("="); - if (key) { - const trimmedKey = key.trim(); - envVars.set(trimmedKey, value?.trim() ?? ""); - // Add the updated variable or preserve existing if not updated - updatedLines.push(`${trimmedKey}=${newEnvVars[trimmedKey] ?? value}`); + continue; + } + + // Handle comment lines + if (trimmedLine.startsWith("#")) { + if (i + 1 < lines.length) { + const nextLine = (lines[i + 1] ?? "").trim(); + if (nextLine && !nextLine.startsWith("#") && nextLine.includes("=")) { + const [possibleKey = ""] = nextLine.split("="); + if ( + Object.prototype.hasOwnProperty.call( + newEnvVars, + possibleKey.trim(), + ) + ) { + // Skip the current comment line if the following key is being updated + continue; + } + } + } + updatedLines.push(line); + continue; + } + + // Process lines in key=value format + if (trimmedLine.includes("=")) { + const [keyPart] = line.split("="); + const key = keyPart?.trim() ?? ""; + if (Object.prototype.hasOwnProperty.call(newEnvVars, key)) { + processedKeys.add(key); + const newValue = newEnvVars[key]; + if (typeof newValue === "object" && newValue !== null) { + updatedLines.push(`# ${newValue.comment}`); + updatedLines.push(`${key}=${newValue.value}`); + } else { + updatedLines.push(`${key}=${newValue}`); + } + } else { + updatedLines.push(line); } + } else { + updatedLines.push(line); } } - // Append new variables that don't already exist - for (const [key, value] of Object.entries(newEnvVars)) { - if (!envVars.has(key)) { - updatedLines.push(`${key}=${value}`); + // Append new variables that do not exist in the file + for (const [key, val] of Object.entries(newEnvVars)) { + if (!processedKeys.has(key)) { + if (typeof val === "object" && val !== null) { + updatedLines.push(`# ${val.comment}`); + updatedLines.push(`${key}=${val.value}`); + } else { + updatedLines.push(`${key}=${val}`); + } } } const updatedContent = updatedLines.join("\n"); - - // Write the updated content back to the .env file await fs.writeFile(filePath, updatedContent, "utf-8"); - return updatedContent; } catch (error) { console.error("Error while updating .env file:", error); diff --git a/plugins/aws/lambda/getUpdateInfo.spec.ts b/plugins/aws/lambda/getUpdateInfo.spec.ts new file mode 100644 index 00000000..91ac857d --- /dev/null +++ b/plugins/aws/lambda/getUpdateInfo.spec.ts @@ -0,0 +1,78 @@ +import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; +import type { Bundle, GetBundlesArgs, UpdateInfo } from "@hot-updater/core"; +import { setupGetUpdateInfoTestSuite } from "@hot-updater/core/test-utils"; +import { mockClient } from "aws-sdk-client-mock"; +import { groupBy } from "es-toolkit"; +import { beforeEach, describe } from "vitest"; +import { getUpdateInfo as getUpdateInfoFromS3 } from "./getUpdateInfo"; + +// @ts-expect-error: Type mismatch in aws-sdk-client-mock +const s3Mock = mockClient(S3Client); + +const createGetUpdateInfo = + (s3: S3Client, bucketName: string) => + async ( + bundles: Bundle[], + { appVersion, bundleId, platform }: GetBundlesArgs, + ): Promise => { + if (bundles.length > 0) { + // Mock target-app-versions.json + const targetVersions = [ + ...new Set(bundles.map((b) => b.targetAppVersion)), + ]; + s3Mock + // @ts-expect-error: Type mismatch in aws-sdk-client-mock + .on(GetObjectCommand, { + Bucket: bucketName, + Key: `${platform}/target-app-versions.json`, + }) + .resolves({ + Body: { + transformToString: () => + Promise.resolve(JSON.stringify(targetVersions)), + }, + } as any); + + // Mock update.json for each version + const bundlesByVersion = groupBy(bundles, (b) => b.targetAppVersion); + + // Set update.json response for each version + for (const [version, versionBundles] of Object.entries( + bundlesByVersion, + )) { + s3Mock + + // @ts-expect-error: Type mismatch in aws-sdk-client-mock + .on(GetObjectCommand, { + Bucket: bucketName, + Key: `${platform}/${version}/update.json`, + }) + .resolves({ + Body: { + transformToString: () => + Promise.resolve(JSON.stringify(versionBundles)), + }, + } as any); + } + } else { + // Return NoSuchKey error when there are no bundles + // @ts-expect-error: Type mismatch in aws-sdk-client-mock + s3Mock.on(GetObjectCommand).rejects(new Error("NoSuchKey")); + } + + return getUpdateInfoFromS3(s3, bucketName, { + appVersion, + bundleId, + platform, + }); + }; + +describe("getUpdateInfo", () => { + beforeEach(() => { + s3Mock.reset(); + }); + + setupGetUpdateInfoTestSuite({ + getUpdateInfo: createGetUpdateInfo(new S3Client({}), "test-bucket"), + }); +}); diff --git a/plugins/aws/lambda/getUpdateInfo.ts b/plugins/aws/lambda/getUpdateInfo.ts new file mode 100644 index 00000000..1e6071e1 --- /dev/null +++ b/plugins/aws/lambda/getUpdateInfo.ts @@ -0,0 +1,63 @@ +import { GetObjectCommand, type S3Client } from "@aws-sdk/client-s3"; +import type { Bundle, Platform } from "@hot-updater/core"; +import { + filterCompatibleAppVersions, + getUpdateInfo as getUpdateInfoJS, +} from "@hot-updater/js"; + +const getS3Json = async (s3: S3Client, bucket: string, key: string) => { + try { + const command = new GetObjectCommand({ Bucket: bucket, Key: key }); + const { Body } = await s3.send(command); + if (!Body) { + return null; + } + const jsonString = await Body.transformToString(); + return JSON.parse(jsonString); + } catch { + return null; + } +}; + +export const getUpdateInfo = async ( + s3: S3Client, + bucketName: string, + { + platform, + appVersion, + bundleId, + }: { + platform: Platform; + appVersion: string; + bundleId: string; + }, +) => { + const targetAppVersions = await getS3Json( + s3, + bucketName, + `${platform}/target-app-versions.json`, + ); + + const matchingVersions = filterCompatibleAppVersions( + targetAppVersions ?? [], + appVersion, + ); + + const results = await Promise.allSettled( + matchingVersions.map((targetAppVersion) => + getS3Json(s3, bucketName, `${platform}/${targetAppVersion}/update.json`), + ), + ); + + const bundles = results + .filter( + (r): r is PromiseFulfilledResult => r.status === "fulfilled", + ) + .flatMap((r) => r.value ?? []); + + return getUpdateInfoJS(bundles, { + platform, + bundleId, + appVersion, + }); +}; diff --git a/plugins/aws/lambda/index.ts b/plugins/aws/lambda/index.ts new file mode 100644 index 00000000..c18534a5 --- /dev/null +++ b/plugins/aws/lambda/index.ts @@ -0,0 +1,91 @@ +import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +import type { CloudFrontRequestHandler } from "aws-lambda"; +import { Hono } from "hono"; +import type { Callback, CloudFrontRequest } from "hono/lambda-edge"; +import { handle } from "hono/lambda-edge"; +import { getUpdateInfo } from "./getUpdateInfo"; + +const s3 = new S3Client(); + +function parseS3Url(url: string) { + try { + const parsedUrl = new URL(url); + const { hostname, pathname } = parsedUrl; + if (!hostname.includes(".s3.")) return { isS3Url: false }; + const [bucket] = hostname.split(".s3"); + const key = pathname.startsWith("/") ? pathname.slice(1) : pathname; + return { isS3Url: true, bucket, key }; + } catch { + return { isS3Url: false }; + } +} + +async function createPresignedUrl(url: string) { + const { isS3Url, bucket, key } = parseS3Url(url); + if (!isS3Url || !bucket || !key) { + return url; + } + // @ts-ignore + return getSignedUrl(s3, new GetObjectCommand({ Bucket: bucket, Key: key }), { + expiresIn: 60, + }); +} + +async function signUpdateInfoFileUrl(updateInfo: any) { + if (updateInfo?.fileUrl) { + updateInfo.fileUrl = await createPresignedUrl(updateInfo.fileUrl); + } + return updateInfo; +} + +type Bindings = { + callback: Callback; + request: CloudFrontRequest; +}; + +const app = new Hono<{ Bindings: Bindings }>(); + +app.get("/api/check-update", async (c) => { + try { + const { headers, origin } = c.env.request; + let bucketName: string | undefined; + if (origin?.s3?.domainName) { + const domainName = origin.s3.domainName; + [bucketName] = domainName.split(".s3"); + } + if (!bucketName) { + return c.json({ error: "Bucket name not found." }, 500); + } + + const bundleId = headers["x-bundle-id"]?.[0]?.value; + const appPlatform = headers["x-app-platform"]?.[0]?.value as + | "ios" + | "android"; + + const appVersion = headers["x-app-version"]?.[0]?.value; + if (!bundleId || !appPlatform || !appVersion) { + return c.json({ error: "Missing required headers." }, 400); + } + + const updateInfo = await getUpdateInfo(s3, bucketName, { + platform: appPlatform, + bundleId, + appVersion, + }); + if (!updateInfo) { + return c.json(null); + } + + const finalInfo = await signUpdateInfoFileUrl(updateInfo); + return c.json(finalInfo); + } catch { + return c.json({ error: "Internal Server Error" }, 500); + } +}); + +app.get("*", async (c) => { + c.env.callback(null, c.env.request); +}); + +export const handler = handle(app) as CloudFrontRequestHandler; diff --git a/plugins/aws/package.json b/plugins/aws/package.json index 98415a18..b7527c75 100644 --- a/plugins/aws/package.json +++ b/plugins/aws/package.json @@ -3,9 +3,9 @@ "type": "module", "version": "0.12.0", "description": "React Native OTA solution for self-hosted", - "main": "dist/index.cjs", - "module": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/src/index.cjs", + "module": "dist/src/index.js", + "types": "dist/src/index.d.ts", "license": "MIT", "repository": "https://github.com/gronxb/hot-updater", "author": "gronxb (https://github.com/gronxb)", @@ -16,20 +16,48 @@ "publishConfig": { "access": "public" }, + "exports": { + ".": { + "import": "./dist/src/index.js", + "require": "./dist/src/index.cjs" + }, + "./sdk": { + "types": "./dist/sdk/index.d.ts", + "import": "./dist/sdk/index.js", + "require": "./dist/sdk/index.cjs" + }, + "./lambda": { + "import": "./dist/lambda/index.js", + "require": "./dist/lambda/index.cjs" + } + }, "files": [ "dist", "package.json" ], "scripts": { - "build": "rslib build", + "build": "tsup", "test:type": "tsc --noEmit" }, "devDependencies": { + "@aws-sdk/s3-request-presigner": "^3.750.0", + "@hot-updater/core": "0.9.0", + "@hot-updater/js": "0.9.0", + "@types/aws-lambda": "^8.10.147", + "@types/node": "^22.13.1", + "aws-sdk-client-mock": "^4.1.0", + "es-toolkit": "^1.32.0", + "hono": "^4.6.3", "mime": "^4.0.4" }, "dependencies": { - "@hot-updater/plugin-core": "0.12.0", + "@aws-sdk/client-cloudfront": "^3.745.0", + "@aws-sdk/client-iam": "^3.749.0", + "@aws-sdk/client-lambda": "^3.744.0", "@aws-sdk/client-s3": "^3.685.0", - "@aws-sdk/lib-storage": "^3.685.0" + "@aws-sdk/credential-providers": "^3.744.0", + "@aws-sdk/lib-storage": "^3.685.0", + "@hot-updater/plugin-core": "0.12.0", + "aws-lambda": "^1.0.7" } } diff --git a/plugins/aws/rslib.config.ts b/plugins/aws/rslib.config.ts deleted file mode 100644 index cd505720..00000000 --- a/plugins/aws/rslib.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { defineConfig } from "@rslib/core"; - -export default defineConfig({ - lib: [ - { - format: "esm", - dts: true, - }, - { - format: "cjs", - dts: true, - }, - ], -}); diff --git a/plugins/aws/sdk/index.ts b/plugins/aws/sdk/index.ts new file mode 100644 index 00000000..71d09c1a --- /dev/null +++ b/plugins/aws/sdk/index.ts @@ -0,0 +1,10 @@ +import CloudFront from "@aws-sdk/client-cloudfront"; +import IAM from "@aws-sdk/client-iam"; +import Lambda from "@aws-sdk/client-lambda"; +import S3 from "@aws-sdk/client-s3"; +import CredentialsProvider from "@aws-sdk/credential-providers"; + +export const SDK = { Lambda, S3, CloudFront, CredentialsProvider, IAM }; + +export type * from "@aws-sdk/client-cloudfront"; +export type { BucketLocationConstraint } from "@aws-sdk/client-s3"; diff --git a/plugins/aws/src/s3Database.spec.ts b/plugins/aws/src/s3Database.spec.ts new file mode 100644 index 00000000..577960e7 --- /dev/null +++ b/plugins/aws/src/s3Database.spec.ts @@ -0,0 +1,453 @@ +// s3Database.spec.ts +import { Buffer } from "buffer"; +import { Readable } from "stream"; +import { + GetObjectCommand, + ListObjectsV2Command, + NoSuchKey, + S3Client, +} from "@aws-sdk/client-s3"; +import type { Bundle } from "@hot-updater/plugin-core"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { s3Database } from "./s3Database"; + +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +const DEFAULT_BUNDLE = { + fileUrl: "http://example.com/bundle.zip", + fileHash: "hash", + gitCommitHash: null, + message: null, + enabled: true, + shouldForceUpdate: false, +} as const; + +const createBundleJson = ( + platform: "ios" | "android", + targetAppVersion: string, + id: string, +): Bundle => ({ + ...DEFAULT_BUNDLE, + id, + platform, + targetAppVersion, +}); + +// fakeStore simulates files stored in S3 +let fakeStore: Record = {}; + +vi.mock("@aws-sdk/lib-storage", () => { + return { + Upload: class { + client: any; + params: any; + constructor({ client, params }: { client: any; params: any }) { + this.client = client; + this.params = params; + } + async done() { + await delay(10); + fakeStore[this.params.Key] = this.params.Body; + } + }, + }; +}); + +beforeEach(() => { + fakeStore = {}; + vi.spyOn(S3Client.prototype, "send").mockImplementation( + async (command: any) => { + await delay(5); + if (command instanceof ListObjectsV2Command) { + const prefix = command.input.Prefix ?? ""; + const keys = Object.keys(fakeStore).filter((key) => + key.startsWith(prefix), + ); + return { + Contents: keys.map((key) => ({ Key: key })), + NextContinuationToken: undefined, + }; + } + if (command instanceof GetObjectCommand) { + const key = command.input.Key; + if (key && fakeStore[key] !== undefined) { + await delay(7); + return { Body: Readable.from([Buffer.from(fakeStore[key])]) }; + } + const error = new Error("NoSuchKey"); + Object.setPrototypeOf(error, NoSuchKey.prototype); + throw error; + } + if (command.constructor.name === "DeleteObjectCommand") { + const key = command.input.Key; + await delay(10); + delete fakeStore[key]; + return {}; + } + throw new Error("Unsupported command in fake S3 client"); + }, + ); +}); + +afterEach(() => { + vi.restoreAllMocks(); +}); + +describe("s3Database plugin", () => { + const bucketName = "test-bucket"; + const s3Config = {}; + // Create plugin: Pass BasePluginArgs like { cwd: "" } + const plugin = s3Database({ bucketName, ...s3Config })({ cwd: "" }); + + it("should append a new bundle and commit to S3", async () => { + // Create new bundle + const bundleKey = "ios/1.0.0/update.json"; + const targetVersionsKey = "ios/target-app-versions.json"; + const newBundle = createBundleJson( + "ios", + "1.0.0", + "00000000-0000-0000-0000-000000000001", + ); + + // Add bundle and commit + await plugin.appendBundle(newBundle); + await plugin.commitBundle(); + + // Verify bundle was properly added to update.json file + const storedBundles = JSON.parse(fakeStore[bundleKey]); + expect(storedBundles).toStrictEqual([newBundle]); + + // Verify new version was added to target-app-versions.json + const versions = JSON.parse(fakeStore[targetVersionsKey]); + expect(versions).toContain("1.0.0"); + + // Verify bundle can be retrieved from memory cache + const fetchedBundle = await plugin.getBundleById( + "00000000-0000-0000-0000-000000000001", + ); + expect(fetchedBundle).toStrictEqual(newBundle); + }); + + it("should update an existing bundle and reflect changes in S3", async () => { + const bundleKey = "android/2.0.0/update.json"; + const targetVersionsKey = "android/target-app-versions.json"; + const initialBundle = createBundleJson( + "android", + "2.0.0", + "00000000-0000-0000-0000-000000000002", + ); + + // Pre-populate bundle data in fakeStore + fakeStore[bundleKey] = JSON.stringify([initialBundle]); + fakeStore[targetVersionsKey] = JSON.stringify(["2.0.0"]); + + // Update bundle and commit + await plugin.getBundles(true); + await plugin.updateBundle("00000000-0000-0000-0000-000000000002", { + enabled: false, + }); + await plugin.commitBundle(); + + // Verify changes were reflected in update.json file + const updatedBundles = JSON.parse(fakeStore[bundleKey]); + expect(updatedBundles).toStrictEqual([ + { + ...initialBundle, + enabled: false, + }, + ]); + }); + + it("should return cached bundles when refresh is false", async () => { + const bundleKey = "ios/3.0.0/update.json"; + const bundle = createBundleJson( + "ios", + "3.0.0", + "00000000-0000-0000-0000-000000000003", + ); + + // Pre-populate bundle data in fakeStore + fakeStore[bundleKey] = JSON.stringify([bundle]); + + // Read bundles from S3 with refresh=true + const bundlesFirst = await plugin.getBundles(true); + expect(bundlesFirst).toStrictEqual([bundle]); + + // Verify cached data is returned even after deleting from fakeStore + delete fakeStore[bundleKey]; + const bundlesSecond = await plugin.getBundles(false); + expect(bundlesSecond).toStrictEqual([bundle]); + }); + + it("should throw an error when trying to update a non-existent bundle", async () => { + await expect( + plugin.updateBundle("nonexistent", { enabled: true }), + ).rejects.toThrow("target bundle version not found"); + }); + + it("should move a bundle from ios/1.x.x/update.json to ios/1.0.2/update.json when targetAppVersion is updated", async () => { + const keyOld = "ios/1.x.x/update.json"; + const keyNew = "ios/1.0.2/update.json"; + const targetVersionsKey = "ios/target-app-versions.json"; + + // Pre-populate bundle data in fakeStore + const oldVersionBundles = [ + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000003"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000002"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000001"), + ]; + + const newVersionBundles = [ + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000005"), + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000004"), + ]; + + // Configure update.json files (_updateJsonKey is added internally during getBundles()) + fakeStore[keyOld] = JSON.stringify(oldVersionBundles); + fakeStore[keyNew] = JSON.stringify(newVersionBundles); + + // Set initial state of target-app-versions.json + fakeStore[targetVersionsKey] = JSON.stringify(["1.x.x", "1.0.2"]); + + // Load all bundle info from S3 into memory cache + await plugin.getBundles(true); + + // Update targetAppVersion of one bundle from ios/1.x.x to 1.0.2 + await plugin.updateBundle("00000000-0000-0000-0000-000000000003", { + targetAppVersion: "1.0.2", + }); + // Commit changes to S3 + await plugin.commitBundle(); + + // ios/1.0.2/update.json should have 3 bundles: 2 existing + 1 moved + const newFileBundles = JSON.parse(fakeStore[keyNew]); + expect(newFileBundles).toStrictEqual([ + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000005"), + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000004"), + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000003"), + ]); + + // And ios/1.x.x/update.json should have 2 remaining bundles + const oldFileBundles = JSON.parse(fakeStore[keyOld]); + expect(oldFileBundles).toStrictEqual([ + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000002"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000001"), + ]); + + // target-app-versions.json should have the new version + const updatedVersions = JSON.parse(fakeStore[targetVersionsKey]); + expect(updatedVersions).toStrictEqual(["1.x.x", "1.0.2"]); + }); + + it("should move all bundles from ios/1.0.2/update.json to ios/1.x.x/update.json when targetAppVersion is updated", async () => { + const keyOld = "ios/1.x.x/update.json"; + const keyNew = "ios/1.0.2/update.json"; + const targetVersionsKey = "ios/target-app-versions.json"; + + // Pre-populate bundle data in fakeStore + const oldVersionBundles = [ + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000003"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000002"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000001"), + ]; + + const newVersionBundles = [ + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000005"), + createBundleJson("ios", "1.0.2", "00000000-0000-0000-0000-000000000004"), + ]; + + // Configure update.json files (_updateJsonKey is added internally during getBundles()) + fakeStore[keyOld] = JSON.stringify(oldVersionBundles); + fakeStore[keyNew] = JSON.stringify(newVersionBundles); + + // Set initial state of target-app-versions.json + fakeStore[targetVersionsKey] = JSON.stringify(["1.x.x", "1.0.2"]); + + await plugin.getBundles(true); + + await plugin.updateBundle("00000000-0000-0000-0000-000000000004", { + targetAppVersion: "1.x.x", + }); + + await plugin.updateBundle("00000000-0000-0000-0000-000000000005", { + targetAppVersion: "1.x.x", + }); + // Commit changes to S3 + await plugin.commitBundle(); + + // ios/1.0.2/update.json file should not exist + expect(fakeStore[keyNew]).toBeUndefined(); + + // And ios/1.x.x/update.json should have all bundles + const oldFileBundles = JSON.parse(fakeStore[keyOld]); + expect(oldFileBundles).toStrictEqual([ + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000005"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000004"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000003"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000002"), + createBundleJson("ios", "1.x.x", "00000000-0000-0000-0000-000000000001"), + ]); + + // target-app-versions.json should be updated + const updatedVersions = JSON.parse(fakeStore[targetVersionsKey]); + expect(updatedVersions).toStrictEqual(["1.x.x"]); + }); + + it("should gather bundles from multiple update.json paths across different platforms", async () => { + // Arrange: Configure different bundle data in multiple update.json files + const iosBundle1 = createBundleJson("ios", "1.0.0", "bundle-ios-1"); + const iosBundle2 = createBundleJson("ios", "2.0.0", "bundle-ios-2"); + const androidBundle1 = createBundleJson( + "android", + "1.0.0", + "bundle-android-1", + ); + + // Valid update.json files + fakeStore["ios/1.0.0/update.json"] = JSON.stringify([iosBundle1]); + fakeStore["ios/2.0.0/update.json"] = JSON.stringify([iosBundle2]); + fakeStore["android/1.0.0/update.json"] = JSON.stringify([androidBundle1]); + + // Invalid files: don't match pattern (should be ignored) + fakeStore["ios/other.json"] = JSON.stringify([]); + fakeStore["android/1.0.0/extra/update.json"] = JSON.stringify([ + createBundleJson("android", "1.0.0", "should-not-be-included"), + ]); + + // Act: Force reload bundle info from S3 + const bundles = await plugin.getBundles(true); + + // Assert: Returned bundle list should only include valid bundles + expect(bundles).toHaveLength(3); + expect(bundles).toEqual( + expect.arrayContaining([iosBundle1, iosBundle2, androidBundle1]), + ); + }); + + it("should return null for non-existent bundle id", async () => { + // Verify null is returned for non-existent bundle ID + const bundle = await plugin.getBundleById("non-existent-id"); + expect(bundle).toBeNull(); + }); + + it("should not modify update.json when no bundles are marked as changed", async () => { + // Verify existing update.json file is preserved + const updateKey = "ios/1.0.0/update.json"; + const iosBundle = createBundleJson("ios", "1.0.0", "bundle-1"); + fakeStore[updateKey] = JSON.stringify([iosBundle]); + // Pre-configure target-app-versions file + const targetKey = "ios/target-app-versions.json"; + fakeStore[targetKey] = JSON.stringify(["1.0.0"]); + + // Call commitBundle but update.json should remain unchanged as no bundles were modified + await plugin.commitBundle(); + + expect(fakeStore[updateKey]).toBe(JSON.stringify([iosBundle])); + expect(JSON.parse(fakeStore[targetKey])).toEqual(["1.0.0"]); + }); + + it("should call onDatabaseUpdated hook after commit", async () => { + // Verify hooks.onDatabaseUpdated is called after commit + const onDatabaseUpdated = vi.fn(); + const pluginWithHook = s3Database( + { bucketName, ...s3Config }, + { onDatabaseUpdated }, + )({ cwd: "" }); + const bundle = createBundleJson("ios", "1.0.0", "hook-test"); + await pluginWithHook.appendBundle(bundle); + await pluginWithHook.commitBundle(); + expect(onDatabaseUpdated).toHaveBeenCalled(); + }); + + it("should sort bundles in descending order based on id", async () => { + // Verify bundles from multiple update.json files are sorted in descending order + const bundleA = createBundleJson("ios", "1.0.0", "A"); + const bundleB = createBundleJson("ios", "1.0.0", "B"); + const bundleC = createBundleJson("ios", "1.0.0", "C"); + // Intentionally store in mixed order in fakeStore + fakeStore["ios/1.0.0/update.json"] = JSON.stringify([bundleB, bundleA]); + fakeStore["ios/2.0.0/update.json"] = JSON.stringify([bundleC]); + + const bundles = await plugin.getBundles(true); + + // Descending order: "C" > "B" > "A" + expect(bundles).toEqual([bundleC, bundleB, bundleA]); + }); + + it("should return a bundle without internal keys from getBundleById", async () => { + // Verify internal management keys (_updateJsonKey, _oldUpdateJsonKey) are removed when fetching by getBundleById + const bundle = createBundleJson("android", "2.0.0", "internal-test"); + fakeStore["android/2.0.0/update.json"] = JSON.stringify([bundle]); + await plugin.getBundles(true); + const fetchedBundle = await plugin.getBundleById("internal-test"); + expect(fetchedBundle).not.toHaveProperty("_updateJsonKey"); + expect(fetchedBundle).not.toHaveProperty("_oldUpdateJsonKey"); + expect(fetchedBundle).toEqual(bundle); + }); + + it("should update a bundle without changing its updateJsonKey if platform and targetAppVersion remain unchanged", async () => { + // Verify updateJsonKey remains unchanged if platform and targetAppVersion stay the same + const bundle = createBundleJson("android", "2.0.0", "same-key-test"); + await plugin.appendBundle(bundle); + // Change only enabled property → path should remain the same + await plugin.updateBundle("same-key-test", { enabled: false }); + await plugin.commitBundle(); + + const updateKey = "android/2.0.0/update.json"; + const storedBundles = JSON.parse(fakeStore[updateKey]); + expect(storedBundles).toEqual([ + { + ...bundle, + enabled: false, + }, + ]); + }); + + it("should return an empty array when no update.json files exist in S3", async () => { + // Verify empty array is returned when no update.json files exist in S3 + fakeStore = {}; // Initialize S3 store + const bundles = await plugin.getBundles(true); + expect(bundles).toEqual([]); + }); + + it("should append multiple bundles and commit them to the correct update.json files", async () => { + // Verify multiple bundles are added to their respective platform/version paths + const bundle1 = createBundleJson("ios", "1.0.0", "multi-1"); + const bundle2 = createBundleJson("android", "2.0.0", "multi-2"); + + await plugin.appendBundle(bundle1); + await plugin.appendBundle(bundle2); + await plugin.commitBundle(); + + const iosUpdateKey = "ios/1.0.0/update.json"; + const androidUpdateKey = "android/2.0.0/update.json"; + + const iosBundles = JSON.parse(fakeStore[iosUpdateKey]); + const androidBundles = JSON.parse(fakeStore[androidUpdateKey]); + + expect(iosBundles).toEqual([bundle1]); + expect(androidBundles).toEqual([bundle2]); + }); + + it("should not update S3 until commitBundle is called", async () => { + const bundleKey = "ios/1.0.0/update.json"; + const newBundle = createBundleJson( + "ios", + "1.0.0", + "00000000-0000-0000-0000-000000000010", + ); + + // Verify fakeStore is empty at start of test + expect(Object.keys(fakeStore)).toHaveLength(0); + + // Call appendBundle: at this point, should only be stored in memory cache, not in S3 (fakeStore) + await plugin.appendBundle(newBundle); + + // S3 should remain unchanged until commitBundle is called + expect(Object.keys(fakeStore)).toHaveLength(0); + + // Now after calling commitBundle, update.json file should be created in S3 (fakeStore) + await plugin.commitBundle(); + expect(Object.keys(fakeStore)).toContain(bundleKey); + }); +}); diff --git a/plugins/aws/src/s3Database.ts b/plugins/aws/src/s3Database.ts index 90428b1a..cb4529de 100644 --- a/plugins/aws/src/s3Database.ts +++ b/plugins/aws/src/s3Database.ts @@ -1,5 +1,7 @@ import { + DeleteObjectCommand, GetObjectCommand, + ListObjectsV2Command, NoSuchKey, S3Client, type S3ClientConfig, @@ -18,84 +20,252 @@ export interface S3DatabaseConfig extends S3ClientConfig { bucketName: string; } +interface BundleWithUpdateJsonKey extends Bundle { + _updateJsonKey: string; + _oldUpdateJsonKey?: string; +} + +/** + * Loads JSON data from S3. + * Returns null if NoSuchKey error occurs. + */ +async function loadJsonFromS3( + client: S3Client, + bucket: string, + key: string, +): Promise { + try { + const { Body } = await client.send( + new GetObjectCommand({ Bucket: bucket, Key: key }), + ); + if (!Body) return null; + const bodyContents = await streamToString(Body); + return JSON.parse(bodyContents) as T; + } catch (e) { + if (e instanceof NoSuchKey) return null; + throw e; + } +} + +/** + * Converts data to JSON string and uploads to S3. + */ +async function uploadJsonToS3( + client: S3Client, + bucket: string, + key: string, + data: T, +) { + const Body = JSON.stringify(data); + const ContentType = mime.getType(key) ?? "application/json"; + const upload = new Upload({ + client, + params: { Bucket: bucket, Key: key, Body, ContentType }, + }); + await upload.done(); +} + export const s3Database = (config: S3DatabaseConfig, hooks?: DatabasePluginHooks) => (_: BasePluginArgs): DatabasePlugin => { const { bucketName, ...s3Config } = config; const client = new S3Client(s3Config); - let bundles: Bundle[] = []; + let bundles: BundleWithUpdateJsonKey[] = []; + const changedIds = new Set(); + + const markChanged = (id: string) => changedIds.add(id); + const PLATFORMS = ["ios", "android"] as const; + + // List update.json paths for each platform in parallel + async function listUpdateJsonKeys(platform: string): Promise { + let continuationToken: string | undefined; + const keys: string[] = []; + const pattern = new RegExp(`^${platform}/[^/]+/update\\.json$`); + do { + const response = await client.send( + new ListObjectsV2Command({ + Bucket: bucketName, + Prefix: `${platform}/`, + ContinuationToken: continuationToken, + }), + ); + const found = (response.Contents ?? []) + .map((item) => item.Key) + .filter((key): key is string => !!key && pattern.test(key)); + keys.push(...found); + continuationToken = response.NextContinuationToken; + } while (continuationToken); + return keys; + } + + // Update target-app-versions.json for each platform + async function updateTargetVersionsForPlatform(platform: string) { + const targetKey = `${platform}/target-app-versions.json`; + const oldTargetVersions = + (await loadJsonFromS3(client, bucketName, targetKey)) ?? []; + const updateKeys = await listUpdateJsonKeys(platform); + const currentVersions = updateKeys.map((key) => key.split("/")[1]); + const newTargetVersions = oldTargetVersions.filter((v) => + currentVersions.includes(v), + ); + for (const v of currentVersions) { + if (!newTargetVersions.includes(v)) newTargetVersions.push(v); + } + await uploadJsonToS3(client, bucketName, targetKey, newTargetVersions); + } + + // Remove bundles to be moved from existing update.json file + async function processRemovals(oldKey: string, removalIds: string[]) { + const currentBundles = + (await loadJsonFromS3(client, bucketName, oldKey)) ?? []; + const updatedBundles = currentBundles.filter( + (b) => !removalIds.includes(b.id), + ); + updatedBundles.sort((a, b) => b.id.localeCompare(a.id)); + if (updatedBundles.length === 0) { + await client.send( + new DeleteObjectCommand({ Bucket: bucketName, Key: oldKey }), + ); + } else { + await uploadJsonToS3(client, bucketName, oldKey, updatedBundles); + } + } + + // Merge changed bundles into new update.json file + async function mergeChangedBundles( + updateJsonKey: string, + changedList: Bundle[], + ) { + const currentBundles = + (await loadJsonFromS3(client, bucketName, updateJsonKey)) ?? + []; + for (const changedBundle of changedList) { + const index = currentBundles.findIndex( + (b) => b.id === changedBundle.id, + ); + if (index >= 0) { + currentBundles[index] = changedBundle; + } else { + currentBundles.push(changedBundle); + } + } + currentBundles.sort((a, b) => b.id.localeCompare(a.id)); + await uploadJsonToS3(client, bucketName, updateJsonKey, currentBundles); + } return { name: "s3Database", + async commitBundle() { - try { - const command = new GetObjectCommand({ - Bucket: bucketName, - Key: "update.json", - }); - await client.send(command); - } catch (e) { - if (!(e instanceof NoSuchKey)) { - throw e; + const changedBundlesByKey: Record = {}; + const removalsByKey: Record = {}; + + // Group changed bundles based on snapshot + for (const bundle of bundles) { + if (changedIds.has(bundle.id)) { + if (bundle._oldUpdateJsonKey) { + removalsByKey[bundle._oldUpdateJsonKey] = + removalsByKey[bundle._oldUpdateJsonKey] || []; + removalsByKey[bundle._oldUpdateJsonKey].push(bundle.id); + } + const currentKey = bundle._updateJsonKey; + if (!currentKey) { + throw new Error( + `Missing _updateJsonKey for bundle id ${bundle.id}`, + ); + } + changedBundlesByKey[currentKey] = + changedBundlesByKey[currentKey] || []; + const { _updateJsonKey, _oldUpdateJsonKey, ...pureBundle } = bundle; + changedBundlesByKey[currentKey].push(pureBundle); } } - const Key = "update.json"; - const Body = JSON.stringify(bundles); - const ContentType = mime.getType(Key) ?? void 0; + // Execute S3 updates sequentially (resolve concurrency issues) + for (const oldKey of Object.keys(removalsByKey)) { + await processRemovals(oldKey, removalsByKey[oldKey]); + } - const upload = new Upload({ - client, - params: { - ContentType, - Bucket: bucketName, - Key, - Body, - }, - }); - await upload.done(); + for (const key of Object.keys(changedBundlesByKey)) { + await mergeChangedBundles(key, changedBundlesByKey[key]); + } + + for (const platform of PLATFORMS) { + await updateTargetVersionsForPlatform(platform); + } + + changedIds.clear(); hooks?.onDatabaseUpdated?.(); }, - async updateBundle(targetBundleId: string, newBundle: Partial) { - bundles = await this.getBundles(); - const targetIndex = bundles.findIndex((u) => u.id === targetBundleId); - if (targetIndex === -1) { + async updateBundle(targetBundleId: string, newBundle: Partial) { + const index = bundles.findIndex((u) => u.id === targetBundleId); + if (index === -1) { throw new Error("target bundle version not found"); } + const original = bundles[index]; + const { + platform: oldPlatform, + targetAppVersion: oldTargetAppVersion, + _updateJsonKey: oldUpdateJsonKey, + } = original; + const newPlatform = newBundle.platform ?? original.platform; + const newTargetAppVersion = + newBundle.targetAppVersion ?? original.targetAppVersion; - Object.assign(bundles[targetIndex], newBundle); - }, - async appendBundle(inputBundle) { - bundles = await this.getBundles(); - bundles.unshift(inputBundle); + if ( + newPlatform !== oldPlatform || + newTargetAppVersion !== oldTargetAppVersion + ) { + original._oldUpdateJsonKey = oldUpdateJsonKey; + original._updateJsonKey = `${newPlatform}/${newTargetAppVersion}/update.json`; + } + Object.assign(original, newBundle); + markChanged(original.id); }, - async getBundleById(bundleId) { - const bundles = await this.getBundles(); - return bundles.find((bundle) => bundle.id === bundleId) ?? null; + + async getBundleById(bundleId: string) { + const bundle = bundles.find((b) => b.id === bundleId); + if (!bundle) return null; + const { _updateJsonKey, _oldUpdateJsonKey, ...pureBundle } = bundle; + return pureBundle; }, + async getBundles(refresh = false) { - if (bundles.length > 0 && !refresh) { - return bundles; + if (!refresh && bundles.length > 0) { + return bundles.map( + ({ _updateJsonKey, _oldUpdateJsonKey, ...bundle }) => bundle, + ); } - try { - const command = new GetObjectCommand({ - Bucket: bucketName, - Key: "update.json", + const platformPromises = PLATFORMS.map(async (platform) => { + const keys = await listUpdateJsonKeys(platform); + const filePromises = keys.map(async (key) => { + const bundlesData = + (await loadJsonFromS3(client, bucketName, key)) ?? []; + return bundlesData.map((bundle) => ({ + ...bundle, + _updateJsonKey: key, + })); }); - const { Body: UpdateJsonBody } = await client.send(command); - const bodyContents = await streamToString(UpdateJsonBody); - const _bundle = JSON.parse(bodyContents); - bundles = _bundle; - return _bundle as Bundle[]; - } catch (e) { - if (e instanceof NoSuchKey) { - return []; - } - throw e; - } + const results = await Promise.all(filePromises); + return results.flat(); + }); + const allBundles = (await Promise.all(platformPromises)).flat(); + allBundles.sort((a, b) => b.id.localeCompare(a.id)); + bundles = allBundles; + return bundles.map( + ({ _updateJsonKey, _oldUpdateJsonKey, ...bundle }) => bundle, + ); + }, + + async appendBundle(inputBundle: Bundle) { + bundles.unshift({ + ...inputBundle, + _updateJsonKey: `${inputBundle.platform}/${inputBundle.targetAppVersion}/update.json`, + }); + markChanged(inputBundle.id); }, }; }; diff --git a/plugins/aws/tsconfig.json b/plugins/aws/tsconfig.json index 8d912ab0..8a818065 100644 --- a/plugins/aws/tsconfig.json +++ b/plugins/aws/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../tsconfig.base.json", - "include": ["src"], + "include": ["src", "sdk", "lambda"], "exclude": ["lib"] } diff --git a/plugins/aws/tsup.config.ts b/plugins/aws/tsup.config.ts new file mode 100644 index 00000000..f9d7ad6f --- /dev/null +++ b/plugins/aws/tsup.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + entry: ["src/index.ts", "sdk/index.ts"], + format: ["esm", "cjs"], + outDir: "dist", + dts: true, + banner: { + js: `import { createRequire } from 'module'; const require = createRequire(import.meta.url);`, + }, + }, + { + entry: ["lambda/index.ts"], + format: ["cjs"], + outDir: "dist/lambda", + }, +]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0859eabf..dda871c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,7 +27,7 @@ importers: version: 1.9.4 '@nx/js': specifier: ^20.3.0 - version: 20.3.0(@babel/traverse@7.25.9)(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(nx@20.3.0(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15)))(typescript@5.7.2) + version: 20.3.0(@babel/traverse@7.25.9)(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(nx@20.3.0(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15)))(typescript@5.7.2) '@rslib/core': specifier: ^0.4.0 version: 0.4.0(typescript@5.7.2) @@ -45,7 +45,7 @@ importers: version: 5.7.2 vitest: specifier: ^2.1.8 - version: 2.1.8(@types/node@22.13.0)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0) + version: 2.1.8(@types/node@22.13.1)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0) docs: devDependencies: @@ -80,6 +80,9 @@ importers: '@babel/runtime': specifier: ^7.20.0 version: 7.26.0 + '@hot-updater/aws': + specifier: workspace:* + version: link:../../plugins/aws '@hot-updater/metro': specifier: workspace:* version: link:../../plugins/metro @@ -191,7 +194,7 @@ importers: version: 0.74.83(@babel/core@7.26.0)(@babel/preset-env@7.23.2(@babel/core@7.26.0)) '@react-native/eslint-config': specifier: 0.74.83 - version: 0.74.83(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)))(prettier@2.8.8)(typescript@5.7.2) + version: 0.74.83(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)))(prettier@2.8.8)(typescript@5.7.2) '@react-native/gradle-plugin': specifier: 0.74.83 version: 0.74.83 @@ -233,7 +236,7 @@ importers: version: 2.2.4 jest: specifier: ^29.6.3 - version: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + version: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) prettier: specifier: 2.8.8 version: 2.8.8 @@ -294,7 +297,7 @@ importers: version: 0.76.2(@babel/preset-env@7.26.0(@babel/core@7.26.0)) '@react-native/eslint-config': specifier: 0.76.1 - version: 0.76.1(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4) + version: 0.76.1(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4) '@react-native/gradle-plugin': specifier: 0.76.1 version: 0.76.1 @@ -333,7 +336,7 @@ importers: version: 2.2.4 jest: specifier: ^29.6.3 - version: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)) + version: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) prettier: specifier: 2.8.8 version: 2.8.8 @@ -570,6 +573,9 @@ importers: '@clack/prompts': specifier: ^0.9.0 version: 0.9.0 + '@hot-updater/aws': + specifier: workspace:* + version: link:../../plugins/aws '@hot-updater/cloudflare': specifier: workspace:* version: link:../../plugins/cloudflare @@ -634,6 +640,9 @@ importers: dayjs: specifier: ^1.11.13 version: 1.11.13 + es-toolkit: + specifier: ^1.32.0 + version: 1.32.0 execa: specifier: ^9.5.2 version: 9.5.2 @@ -692,16 +701,55 @@ importers: plugins/aws: dependencies: + '@aws-sdk/client-cloudfront': + specifier: ^3.745.0 + version: 3.745.0 + '@aws-sdk/client-iam': + specifier: ^3.749.0 + version: 3.749.0 + '@aws-sdk/client-lambda': + specifier: ^3.744.0 + version: 3.744.0 '@aws-sdk/client-s3': specifier: ^3.685.0 version: 3.685.0 + '@aws-sdk/credential-providers': + specifier: ^3.744.0 + version: 3.744.0 '@aws-sdk/lib-storage': specifier: ^3.685.0 version: 3.685.0(@aws-sdk/client-s3@3.685.0) '@hot-updater/plugin-core': specifier: workspace:* version: link:../plugin-core + aws-lambda: + specifier: ^1.0.7 + version: 1.0.7 devDependencies: + '@aws-sdk/s3-request-presigner': + specifier: ^3.750.0 + version: 3.750.0 + '@hot-updater/core': + specifier: workspace:* + version: link:../../packages/core + '@hot-updater/js': + specifier: workspace:* + version: link:../js + '@types/aws-lambda': + specifier: ^8.10.147 + version: 8.10.147 + '@types/node': + specifier: ^22.13.1 + version: 22.13.1 + aws-sdk-client-mock: + specifier: ^4.1.0 + version: 4.1.0 + es-toolkit: + specifier: ^1.32.0 + version: 1.32.0 + hono: + specifier: ^4.6.3 + version: 4.6.3 mime: specifier: ^4.0.4 version: 4.0.4 @@ -810,7 +858,7 @@ importers: devDependencies: vitest: specifier: 2.1.8 - version: 2.1.8(@types/node@22.13.0)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0) + version: 2.1.8(@types/node@22.13.1)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0) plugins/plugin-core: dependencies: @@ -942,6 +990,22 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + '@aws-sdk/client-cloudfront@3.745.0': + resolution: {integrity: sha512-IwTmuHPM5MR4fMSYa3Ix0kkfKfvLxg6ptoE2tHYTgPORLjAorD9O6b3slzgAsv2l1tq4XBxFKsAwdHjqzx4Eqg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-cognito-identity@3.744.0': + resolution: {integrity: sha512-Z6NAl6pXSOO+9XYh3yWmvrzsE2qbc3abD9LDWNwj1j08fNF0gcKTMZol90dz7J3edaEbt2DBAze/I1cU/QgQCQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-iam@3.749.0': + resolution: {integrity: sha512-u4Rpf2x9a+0Huj1e6++usrQutjoyI0bmbSv/NuqwMSLKktkRaEuNQWgujA/1ZB6VokYeZ8Vt88iIPgBLh/jLSw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-lambda@3.744.0': + resolution: {integrity: sha512-XPWPuvRkrabJ9jMBeEurn2vXVo40umeoeV0+nAERtG6mt9dB8d3gobHROBG5iwWJV1oqBDn9E/ZN8WDahvM1BQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/client-s3@3.685.0': resolution: {integrity: sha512-ClvMeQHbLhWkpxnVymo4qWS5/yZcPXjorDbSday3joCWYWCSHTO409nWd+jx6eA4MKT/EY/uJ6ZBJRFfByKLuA==} engines: {node: '>=16.0.0'} @@ -956,6 +1020,14 @@ packages: resolution: {integrity: sha512-PYH9RFUMYLFl66HSBq4tIx6fHViMLkhJHTYJoJONpBs+Td+NwVJ895AdLtDsBIhMS0YseCbPpuyjUCJgsUrwUw==} engines: {node: '>=16.0.0'} + '@aws-sdk/client-sso@3.744.0': + resolution: {integrity: sha512-mzJxPQ9mcnNY50pi7+pxB34/Dt7PUn0OgkashHdJPTnavoriLWvPcaQCG1NEVAtyzxNdowhpi4KjC+aN1EwAeA==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-sso@3.749.0': + resolution: {integrity: sha512-ecmuDu8EPya1LDpGRtpgN7C9PHayDh8EaW37ZBKhuxA7cg099yvTFqsGngwRXbhNjKJ4oVa9OUe0EDnu60atYA==} + engines: {node: '>=18.0.0'} + '@aws-sdk/client-sts@3.682.0': resolution: {integrity: sha512-xKuo4HksZ+F8m9DOfx/ZuWNhaPuqZFPwwy0xqcBT6sWH7OAuBjv/fnpOTzyQhpVTWddlf+ECtMAMrxjxuOExGQ==} engines: {node: '>=16.0.0'} @@ -964,38 +1036,114 @@ packages: resolution: {integrity: sha512-CS6PWGX8l4v/xyvX8RtXnBisdCa5+URzKd0L6GvHChype9qKUVxO/Gg6N/y43Hvg7MNWJt9FBPNWIxUB+byJwg==} engines: {node: '>=16.0.0'} + '@aws-sdk/core@3.744.0': + resolution: {integrity: sha512-R0XLfDDq7MAXYyDf7tPb+m0R7gmzTRRDtPNQ5jvuq8dbkefph5gFMkxZ2zSx7dfTsfYHhBPuTBsQ0c5Xjal3Vg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/core@3.749.0': + resolution: {integrity: sha512-w5Jj573+XKwrDNZUjUJDXL5upx+RCw64TLq3Zk8FVg9MsgkzAPorQ9qmzffi6os+PWngd3pFmD8q5y+Y35LpFQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/core@3.750.0': + resolution: {integrity: sha512-bZ5K7N5L4+Pa2epbVpUQqd1XLG2uU8BGs/Sd+2nbgTf+lNQJyIxAg/Qsrjz9MzmY8zzQIeRQEkNmR6yVAfCmmQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-cognito-identity@3.744.0': + resolution: {integrity: sha512-NUxBVFzoVBmS6JH1sK8nzw8AAOI5hCM+lMLa0Dtwxk+dRIe6XRpU9wHkIbaA6Adwp8qvvyYZsgymuMvoAzGmcQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-env@3.679.0': resolution: {integrity: sha512-EdlTYbzMm3G7VUNAMxr9S1nC1qUNqhKlAxFU8E7cKsAe8Bp29CD5HAs3POc56AVo9GC4yRIS+/mtlZSmrckzUA==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-env@3.744.0': + resolution: {integrity: sha512-hyjC7xqzAeERorYYjhQG1ivcr1XlxgfBpa+r4pG29toFG60mACyVzaR7+og3kgzjRFAB7D1imMxPQyEvQ1QokA==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-env@3.749.0': + resolution: {integrity: sha512-bhB1ds5QzcSfmCTbjVessXy8xHJROota6wOhFtBsL1aZRQyNN2a9h2QS6xkxjmqVE3yHBsPz+OiSOeLn0kxm7Q==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-http@3.679.0': resolution: {integrity: sha512-ZoKLubW5DqqV1/2a3TSn+9sSKg0T8SsYMt1JeirnuLJF0mCoYFUaWMyvxxKuxPoqvUsaycxKru4GkpJ10ltNBw==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-http@3.744.0': + resolution: {integrity: sha512-k+P1Tl5ewBvVByR6hB726qFIzANgQVf2cY87hZ/e09pQYlH4bfBcyY16VJhkqYnKmv6HMdWxKHX7D8nwlc8Obg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-http@3.749.0': + resolution: {integrity: sha512-enFGT8uvETbE6+4bDA2aTOrA/83GrIVPpg2g2r7MwJb36jreXA3KDXaP/5jQsxyIZW70cnYNl/Cawdd4ZXs7CQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-ini@3.682.0': resolution: {integrity: sha512-6eqWeHdK6EegAxqDdiCi215nT3QZPwukgWAYuVxNfJ/5m0/P7fAzF+D5kKVgByUvGJEbq/FEL8Fw7OBe64AA+g==} engines: {node: '>=16.0.0'} peerDependencies: '@aws-sdk/client-sts': ^3.682.0 + '@aws-sdk/credential-provider-ini@3.744.0': + resolution: {integrity: sha512-hjEWgkF86tkvg8PIsDiB3KkTj7z8ZFGR0v0OLQYD47o17q1qfoMzZmg9wae3wXp9KzU+lZETo+8oMqX9a+7aVQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-ini@3.749.0': + resolution: {integrity: sha512-OB4AGK61lQdoW2mTmaMBw8L+eBo7wF3YJZXwqFI7M2cQe9WtfuKGIxbYWMBMzoLvEtmsbzeppoZZUezooaIclg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-node@3.682.0': resolution: {integrity: sha512-HSmDqZcBVZrTctHCT9m++vdlDfJ1ARI218qmZa+TZzzOFNpKWy6QyHMEra45GB9GnkkMmV6unoDSPMuN0AqcMg==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-node@3.744.0': + resolution: {integrity: sha512-4oUfRd6pe/VGmKoav17pPoOO0WP0L6YXmHqtJHSDmFUOAa+Vh0ZRljTj/yBdleRgdO6rOfdWqoGLFSFiAZDrsQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-node@3.749.0': + resolution: {integrity: sha512-1QGstZmGmgmY0rLSTAURlBJdR4s2PRYiZh6dS4HkzzQu7xVDWoCMD+2F7dolsNA8ChTNx2OvBW80n3O9QPICCg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-process@3.679.0': resolution: {integrity: sha512-u/p4TV8kQ0zJWDdZD4+vdQFTMhkDEJFws040Gm113VHa/Xo1SYOjbpvqeuFoz6VmM0bLvoOWjxB9MxnSQbwKpQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-process@3.744.0': + resolution: {integrity: sha512-m0d/pDBIaiEAAxWXt/c79RHsKkUkyPOvF2SAMRddVhhOt1GFZI4ml+3f4drmAZfXldIyJmvJTJJqWluVPwTIqQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-process@3.749.0': + resolution: {integrity: sha512-C/cgg/AhRabybZRY9mJ6KDz8uqfasWKuFIFGzTpeb/MIDIL53ZqP61CspiQJTRvC4zlFGqvm43XefphfrBGGlQ==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-sso@3.682.0': resolution: {integrity: sha512-h7IH1VsWgV6YAJSWWV6y8uaRjGqLY3iBpGZlXuTH/c236NMLaNv+WqCBLeBxkFGUb2WeQ+FUPEJDCD69rgLIkg==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-sso@3.744.0': + resolution: {integrity: sha512-xdMufTZOvpbDoDPI2XLu0/Rg3qJ/txpS8IJR63NsCGotHJZ/ucLNKwTcGS40hllZB8qSHTlvmlOzElDahTtx/A==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-sso@3.749.0': + resolution: {integrity: sha512-bQNgWcYk10fYOvFwcLskYYVNLO3KMgmV1ip9ieapJb9JDg6bSBaXNjIDhdpK4biTOfrV+adtDO5EU93ogpmAWA==} + engines: {node: '>=18.0.0'} + '@aws-sdk/credential-provider-web-identity@3.679.0': resolution: {integrity: sha512-a74tLccVznXCaBefWPSysUcLXYJiSkeUmQGtalNgJ1vGkE36W5l/8czFiiowdWdKWz7+x6xf0w+Kjkjlj42Ung==} engines: {node: '>=16.0.0'} peerDependencies: '@aws-sdk/client-sts': ^3.679.0 + '@aws-sdk/credential-provider-web-identity@3.744.0': + resolution: {integrity: sha512-cNk93GZxORzqEojWfXdrPBF6a7Nu3LpPCWG5mV+lH2tbuGsmw6XhKkwpt7o+OiIP4tKCpHlvqOD8f1nmhe1KDA==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.749.0': + resolution: {integrity: sha512-jzHk6i4G4dnXL+L+qeILguDCiIhA1rNvJzB5lTts4R8OdmNkG12bGbYL8bL4O1b5qCimlo7HS0IZIby0pS7rcg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/credential-providers@3.744.0': + resolution: {integrity: sha512-8vXnKA/TklSx6HdF88RVohtsvYNuGP9nm5RTCSGbWVR7+xEU/Eh15B+EKoGasCjZW7/9GxnSULp0DN1msCR23A==} + engines: {node: '>=18.0.0'} + '@aws-sdk/lib-storage@3.685.0': resolution: {integrity: sha512-6oGVXmtSr04xzq5XVBHj3yZTWJVfhUElEER5Bg9SrdoWTFRUsjnbOzqOAhYmlrEmEoGTtnZyj7wDI2EY7iCBTQ==} engines: {node: '>=16.0.0'} @@ -1018,6 +1166,10 @@ packages: resolution: {integrity: sha512-y176HuQ8JRY3hGX8rQzHDSbCl9P5Ny9l16z4xmaiLo+Qfte7ee4Yr3yaAKd7GFoJ3/Mhud2XZ37fR015MfYl2w==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-host-header@3.734.0': + resolution: {integrity: sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-location-constraint@3.679.0': resolution: {integrity: sha512-SA1C1D3XgoKTGxyNsOqd016ONpk46xJLWDgJUd00Zb21Ox5wYCoY6aDRKiaMRW+1VfCJdezs1Do3XLyIU9KxyA==} engines: {node: '>=16.0.0'} @@ -1026,14 +1178,26 @@ packages: resolution: {integrity: sha512-0vet8InEj7nvIvGKk+ch7bEF5SyZ7Us9U7YTEgXPrBNStKeRUsgwRm0ijPWWd0a3oz2okaEwXsFl7G/vI0XiEA==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-logger@3.734.0': + resolution: {integrity: sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-recursion-detection@3.679.0': resolution: {integrity: sha512-sQoAZFsQiW/LL3DfKMYwBoGjYDEnMbA9WslWN8xneCmBAwKo6IcSksvYs23PP8XMIoBGe2I2J9BSr654XWygTQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-recursion-detection@3.734.0': + resolution: {integrity: sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-sdk-s3@3.685.0': resolution: {integrity: sha512-C4w92b3A99NbghrA2Ssw6y1RbDF3I3Bgzi2Izh0pXgyIoDiX0xs9bUs/FGYLK4uepYr78DAZY8DwEpzjWIXkSA==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-sdk-s3@3.750.0': + resolution: {integrity: sha512-3H6Z46cmAQCHQ0z8mm7/cftY5ifiLfCjbObrbyyp2fhQs9zk6gCKzIX8Zjhw0RMd93FZi3ebRuKJWmMglf4Itw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-ssec@3.679.0': resolution: {integrity: sha512-4GNUxXbs1M71uFHRiCAZtN0/g23ogI9YjMe5isAuYMHXwDB3MhqF7usKf954mBP6tplvN44vYlbJ84faaLrTtg==} engines: {node: '>=16.0.0'} @@ -1042,32 +1206,84 @@ packages: resolution: {integrity: sha512-7TyvYR9HdGH1/Nq0eeApUTM4izB6rExiw87khVYuJwZHr6FmvIL1FsOVFro/4WlXa0lg4LiYOm/8H8dHv+fXTg==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-user-agent@3.744.0': + resolution: {integrity: sha512-ROUbDQHfVWiBHXd4m9E9mKj1Azby8XCs8RC8OCf9GVH339GSE6aMrPJSzMlsV1LmzPdPIypgp5qqh5NfSrKztg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/middleware-user-agent@3.749.0': + resolution: {integrity: sha512-dNRkZtiM8OoGb/h2Fgrgvty9ltYEubzsD5FH+VN14RrluertLQMmqHrgvq7JoAXFf7MJy+uwhRu4V6pf1sZR/w==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/nested-clients@3.744.0': + resolution: {integrity: sha512-Mnrlh4lRY1gZQnKvN2Lh/5WXcGkzC41NM93mtn2uaqOh+DZLCXCttNCfbUesUvYJLOo3lYaOpiDsjTkPVB1yjw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/nested-clients@3.749.0': + resolution: {integrity: sha512-5L8OuVojcVQAZw+iVXTaw88AZTlMw8fD51lB6spzbZdNLl6dd5Iz1JVJAOUl2mTAZXRiN5Q9VECwY1yMgWweAw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/region-config-resolver@3.679.0': resolution: {integrity: sha512-Ybx54P8Tg6KKq5ck7uwdjiKif7n/8g1x+V0V9uTjBjRWqaIgiqzXwKWoPj6NCNkE7tJNtqI4JrNxp/3S3HvmRw==} engines: {node: '>=16.0.0'} + '@aws-sdk/region-config-resolver@3.734.0': + resolution: {integrity: sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/s3-request-presigner@3.750.0': + resolution: {integrity: sha512-G4GNngNQlh9EyJZj2WKOOikX0Fev1WSxTV/XJugaHlpnVriebvi3GzolrgxUpRrcGpFGWjmAxLi/gYxTUla1ow==} + engines: {node: '>=18.0.0'} + '@aws-sdk/signature-v4-multi-region@3.685.0': resolution: {integrity: sha512-IHLwuAZGqfUWVrNqw0ugnBa7iL8uBP4x6A7bfBDXRXWCWjUCed/1/D//0lKDHwpFkV74fGW6KoBacnWSUlXmwA==} engines: {node: '>=16.0.0'} + '@aws-sdk/signature-v4-multi-region@3.750.0': + resolution: {integrity: sha512-RA9hv1Irro/CrdPcOEXKwJ0DJYJwYCsauGEdRXihrRfy8MNSR9E+mD5/Fr5Rxjaq5AHM05DYnN3mg/DU6VwzSw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/token-providers@3.679.0': resolution: {integrity: sha512-1/+Zso/x2jqgutKixYFQEGli0FELTgah6bm7aB+m2FAWH4Hz7+iMUsazg6nSWm714sG9G3h5u42Dmpvi9X6/hA==} engines: {node: '>=16.0.0'} peerDependencies: '@aws-sdk/client-sso-oidc': ^3.679.0 + '@aws-sdk/token-providers@3.744.0': + resolution: {integrity: sha512-v/1+lWkDCd60Ei6oyhJqli6mTsPEVepLoSMB50vHUVlJP0fzXu/3FMje90/RzeUoh/VugZQJCEv/NNpuC6wztg==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/token-providers@3.749.0': + resolution: {integrity: sha512-s3ExVWoNZan6U7ljMqjiHq3bOe4EqL+U+cVPwqNxAsMaJpGyCiA8VQFlXNGg0EPAFbz/0DVBcozYht6/vyH3sg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/types@3.679.0': resolution: {integrity: sha512-NwVq8YvInxQdJ47+zz4fH3BRRLC6lL+WLkvr242PVBbUOLRyK/lkwHlfiKUoeVIMyK5NF+up6TRg71t/8Bny6Q==} engines: {node: '>=16.0.0'} + '@aws-sdk/types@3.734.0': + resolution: {integrity: sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg==} + engines: {node: '>=18.0.0'} + '@aws-sdk/util-arn-parser@3.679.0': resolution: {integrity: sha512-CwzEbU8R8rq9bqUFryO50RFBlkfufV9UfMArHPWlo+lmsC+NlSluHQALoj6Jkq3zf5ppn1CN0c1DDLrEqdQUXg==} engines: {node: '>=16.0.0'} + '@aws-sdk/util-arn-parser@3.723.0': + resolution: {integrity: sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==} + engines: {node: '>=18.0.0'} + '@aws-sdk/util-endpoints@3.679.0': resolution: {integrity: sha512-YL6s4Y/1zC45OvddvgE139fjeWSKKPgLlnfrvhVL7alNyY9n7beR4uhoDpNrt5mI6sn9qiBF17790o+xLAXjjg==} engines: {node: '>=16.0.0'} + '@aws-sdk/util-endpoints@3.743.0': + resolution: {integrity: sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/util-format-url@3.734.0': + resolution: {integrity: sha512-TxZMVm8V4aR/QkW9/NhujvYpPZjUYqzLwSge5imKZbWFR806NP7RMwc5ilVuHF/bMOln/cVHkl42kATElWBvNw==} + engines: {node: '>=18.0.0'} + '@aws-sdk/util-locate-window@3.310.0': resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==} engines: {node: '>=14.0.0'} @@ -1075,6 +1291,9 @@ packages: '@aws-sdk/util-user-agent-browser@3.679.0': resolution: {integrity: sha512-CusSm2bTBG1kFypcsqU8COhnYc6zltobsqs3nRrvYqYaOqtMnuE46K4XTWpnzKgwDejgZGOE+WYyprtAxrPvmQ==} + '@aws-sdk/util-user-agent-browser@3.734.0': + resolution: {integrity: sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng==} + '@aws-sdk/util-user-agent-node@3.682.0': resolution: {integrity: sha512-so5s+j0gPoTS0HM4HPL+G0ajk0T6cQAg8JXzRgvyiQAxqie+zGCZAV3VuVeMNWMVbzsgZl0pYZaatPFTLG/AxA==} engines: {node: '>=16.0.0'} @@ -1084,10 +1303,32 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.744.0': + resolution: {integrity: sha512-BJURjwIXhNa4heXkLC0+GcL+8wVXaU7JoyW6ckdvp93LL+sVHeR1d5FxXZHQW/pMI4E3gNlKyBqjKaT75tObNQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/util-user-agent-node@3.749.0': + resolution: {integrity: sha512-uBzolGGrwvZKhpYlGIy9tw6gRdqVs2zyjjXUiifdgbr3WiQXJe8sE1KhLjzyN/VOPcZB0rY34ybqiKEDOymOeQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + '@aws-sdk/xml-builder@3.679.0': resolution: {integrity: sha512-nPmhVZb39ty5bcQ7mAwtjezBcsBqTYZ9A2D9v/lE92KCLdu5RhSkPH7O71ZqbZx1mUSg9fAOxHPiG79U5VlpLQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/xml-builder@3.734.0': + resolution: {integrity: sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ==} + engines: {node: '>=18.0.0'} + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -4306,13 +4547,32 @@ packages: '@sinonjs/commons@3.0.0': resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@11.2.2': + resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + + '@sinonjs/samsam@8.0.2': + resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} + + '@sinonjs/text-encoding@0.7.3': + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + '@smithy/abort-controller@3.1.6': resolution: {integrity: sha512-0XuhuHQlEqbNQZp7QxxrFTdVWdwxch4vjxYgfInF91hZFkPxf9QDrdQka0KfxFMPqLNzSw0b95uGTrLliQUavQ==} engines: {node: '>=16.0.0'} + '@smithy/abort-controller@4.0.1': + resolution: {integrity: sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==} + engines: {node: '>=18.0.0'} + '@smithy/chunked-blob-reader-native@3.0.1': resolution: {integrity: sha512-VEYtPvh5rs/xlyqpm5NRnfYLZn+q0SRPELbvBV+C/G7IQ+ouTuo+NKKa3ShG5OaFR8NYVMXls9hPYLTvIKKDrQ==} @@ -4323,39 +4583,79 @@ packages: resolution: {integrity: sha512-Uh0Sz9gdUuz538nvkPiyv1DZRX9+D15EKDtnQP5rYVAzM/dnYk3P8cg73jcxyOitPgT3mE3OVj7ky7sibzHWkw==} engines: {node: '>=16.0.0'} + '@smithy/config-resolver@4.0.1': + resolution: {integrity: sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==} + engines: {node: '>=18.0.0'} + '@smithy/core@2.5.1': resolution: {integrity: sha512-DujtuDA7BGEKExJ05W5OdxCoyekcKT3Rhg1ZGeiUWaz2BJIWXjZmsG/DIP4W48GHno7AQwRsaCb8NcBgH3QZpg==} engines: {node: '>=16.0.0'} + '@smithy/core@3.1.2': + resolution: {integrity: sha512-htwQXkbdF13uwwDevz9BEzL5ABK+1sJpVQXywwGSH973AVOvisHNfpcB8A8761G6XgHoS2kHPqc9DqHJ2gp+/Q==} + engines: {node: '>=18.0.0'} + + '@smithy/core@3.1.4': + resolution: {integrity: sha512-wFExFGK+7r2wYriOqe7RRIBNpvxwiS95ih09+GSLRBdoyK/O1uZA7K7pKesj5CBvwJuSBeXwLyR88WwIAY+DGA==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@3.2.5': resolution: {integrity: sha512-4FTQGAsuwqTzVMmiRVTn0RR9GrbRfkP0wfu/tXWVHd2LgNpTY0uglQpIScXK4NaEyXbB3JmZt8gfVqO50lP8wg==} engines: {node: '>=16.0.0'} + '@smithy/credential-provider-imds@4.0.1': + resolution: {integrity: sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-codec@3.1.7': resolution: {integrity: sha512-kVSXScIiRN7q+s1x7BrQtZ1Aa9hvvP9FeCqCdBxv37GimIHgBCOnZ5Ip80HLt0DhnAKpiobFdGqTFgbaJNrazA==} + '@smithy/eventstream-codec@4.0.1': + resolution: {integrity: sha512-Q2bCAAR6zXNVtJgifsU16ZjKGqdw/DyecKNgIgi7dlqw04fqDu0mnq+JmGphqheypVc64CYq3azSuCpAdFk2+A==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-browser@3.0.11': resolution: {integrity: sha512-Pd1Wnq3CQ/v2SxRifDUihvpXzirJYbbtXfEnnLV/z0OGCTx/btVX74P86IgrZkjOydOASBGXdPpupYQI+iO/6A==} engines: {node: '>=16.0.0'} + '@smithy/eventstream-serde-browser@4.0.1': + resolution: {integrity: sha512-HbIybmz5rhNg+zxKiyVAnvdM3vkzjE6ccrJ620iPL8IXcJEntd3hnBl+ktMwIy12Te/kyrSbUb8UCdnUT4QEdA==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-config-resolver@3.0.8': resolution: {integrity: sha512-zkFIG2i1BLbfoGQnf1qEeMqX0h5qAznzaZmMVNnvPZz9J5AWBPkOMckZWPedGUPcVITacwIdQXoPcdIQq5FRcg==} engines: {node: '>=16.0.0'} + '@smithy/eventstream-serde-config-resolver@4.0.1': + resolution: {integrity: sha512-lSipaiq3rmHguHa3QFF4YcCM3VJOrY9oq2sow3qlhFY+nBSTF/nrO82MUQRPrxHQXA58J5G1UnU2WuJfi465BA==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-node@3.0.10': resolution: {integrity: sha512-hjpU1tIsJ9qpcoZq9zGHBJPBOeBGYt+n8vfhDwnITPhEre6APrvqq/y3XMDEGUT2cWQ4ramNqBPRbx3qn55rhw==} engines: {node: '>=16.0.0'} + '@smithy/eventstream-serde-node@4.0.1': + resolution: {integrity: sha512-o4CoOI6oYGYJ4zXo34U8X9szDe3oGjmHgsMGiZM0j4vtNoT+h80TLnkUcrLZR3+E6HIxqW+G+9WHAVfl0GXK0Q==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-universal@3.0.10': resolution: {integrity: sha512-ewG1GHbbqsFZ4asaq40KmxCmXO+AFSM1b+DcO2C03dyJj/ZH71CiTg853FSE/3SHK9q3jiYQIFjlGSwfxQ9kww==} engines: {node: '>=16.0.0'} + '@smithy/eventstream-serde-universal@4.0.1': + resolution: {integrity: sha512-Z94uZp0tGJuxds3iEAZBqGU2QiaBHP4YytLUjwZWx+oUeohCsLyUm33yp4MMBmhkuPqSbQCXq5hDet6JGUgHWA==} + engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@3.2.9': resolution: {integrity: sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A==} '@smithy/fetch-http-handler@4.0.0': resolution: {integrity: sha512-MLb1f5tbBO2X6K4lMEKJvxeLooyg7guq48C2zKr4qM7F2Gpkz4dc+hdSgu77pCJ76jVqFBjZczHYAs6dp15N+g==} + '@smithy/fetch-http-handler@5.0.1': + resolution: {integrity: sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA==} + engines: {node: '>=18.0.0'} + '@smithy/hash-blob-browser@3.1.7': resolution: {integrity: sha512-4yNlxVNJifPM5ThaA5HKnHkn7JhctFUHvcaz6YXxHlYOSIrzI6VKQPTN8Gs1iN5nqq9iFcwIR9THqchUCouIfg==} @@ -4363,6 +4663,10 @@ packages: resolution: {integrity: sha512-tlNQYbfpWXHimHqrvgo14DrMAgUBua/cNoz9fMYcDmYej7MAmUcjav/QKQbFc3NrcPxeJ7QClER4tWZmfwoPng==} engines: {node: '>=16.0.0'} + '@smithy/hash-node@4.0.1': + resolution: {integrity: sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w==} + engines: {node: '>=18.0.0'} + '@smithy/hash-stream-node@3.1.7': resolution: {integrity: sha512-xMAsvJ3hLG63lsBVi1Hl6BBSfhd8/Qnp8fC06kjOpJvyyCEXdwHITa5Kvdsk6gaAXLhbZMhQMIGvgUbfnJDP6Q==} engines: {node: '>=16.0.0'} @@ -4370,6 +4674,10 @@ packages: '@smithy/invalid-dependency@3.0.8': resolution: {integrity: sha512-7Qynk6NWtTQhnGTTZwks++nJhQ1O54Mzi7fz4PqZOiYXb4Z1Flpb2yRvdALoggTS8xjtohWUM+RygOtB30YL3Q==} + '@smithy/invalid-dependency@4.0.1': + resolution: {integrity: sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ==} + engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@2.0.0': resolution: {integrity: sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==} engines: {node: '>=14.0.0'} @@ -4378,6 +4686,10 @@ packages: resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} engines: {node: '>=16.0.0'} + '@smithy/is-array-buffer@4.0.0': + resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==} + engines: {node: '>=18.0.0'} + '@smithy/md5-js@3.0.8': resolution: {integrity: sha512-LwApfTK0OJ/tCyNUXqnWCKoE2b4rDSr4BJlDAVCkiWYeHESr+y+d5zlAanuLW6fnitVJRD/7d9/kN/ZM9Su4mA==} @@ -4385,80 +4697,172 @@ packages: resolution: {integrity: sha512-T4dIdCs1d/+/qMpwhJ1DzOhxCZjZHbHazEPJWdB4GDi2HjIZllVzeBEcdJUN0fomV8DURsgOyrbEUzg3vzTaOg==} engines: {node: '>=16.0.0'} + '@smithy/middleware-content-length@4.0.1': + resolution: {integrity: sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@3.2.1': resolution: {integrity: sha512-wWO3xYmFm6WRW8VsEJ5oU6h7aosFXfszlz3Dj176pTij6o21oZnzkCLzShfmRaaCHDkBXWBdO0c4sQAvLFP6zA==} engines: {node: '>=16.0.0'} + '@smithy/middleware-endpoint@4.0.3': + resolution: {integrity: sha512-YdbmWhQF5kIxZjWqPIgboVfi8i5XgiYMM7GGKFMTvBei4XjNQfNv8sukT50ITvgnWKKKpOtp0C0h7qixLgb77Q==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-endpoint@4.0.5': + resolution: {integrity: sha512-cPzGZV7qStHwboFrm6GfrzQE+YDiCzWcTh4+7wKrP/ZQ4gkw+r7qDjV8GjM4N0UYsuUyLfpzLGg5hxsYTU11WA==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@3.0.25': resolution: {integrity: sha512-m1F70cPaMBML4HiTgCw5I+jFNtjgz5z5UdGnUbG37vw6kh4UvizFYjqJGHvicfgKMkDL6mXwyPp5mhZg02g5sg==} engines: {node: '>=16.0.0'} + '@smithy/middleware-retry@4.0.4': + resolution: {integrity: sha512-wmxyUBGHaYUqul0wZiset4M39SMtDBOtUr2KpDuftKNN74Do9Y36Go6Eqzj9tL0mIPpr31ulB5UUtxcsCeGXsQ==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-retry@4.0.6': + resolution: {integrity: sha512-s8QzuOQnbdvRymD9Gt9c9zMq10wUQAHQ3z72uirrBHCwZcLTrL5iCOuVTMdka2IXOYhQE890WD5t6G24+F+Qcg==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@3.0.8': resolution: {integrity: sha512-Xg2jK9Wc/1g/MBMP/EUn2DLspN8LNt+GMe7cgF+Ty3vl+Zvu+VeZU5nmhveU+H8pxyTsjrAkci8NqY6OuvZnjA==} engines: {node: '>=16.0.0'} + '@smithy/middleware-serde@4.0.2': + resolution: {integrity: sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@3.0.8': resolution: {integrity: sha512-d7ZuwvYgp1+3682Nx0MD3D/HtkmZd49N3JUndYWQXfRZrYEnCWYc8BHcNmVsPAp9gKvlurdg/mubE6b/rPS9MA==} engines: {node: '>=16.0.0'} + '@smithy/middleware-stack@4.0.1': + resolution: {integrity: sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA==} + engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@3.1.9': resolution: {integrity: sha512-qRHoah49QJ71eemjuS/WhUXB+mpNtwHRWQr77J/m40ewBVVwvo52kYAmb7iuaECgGTTcYxHS4Wmewfwy++ueew==} engines: {node: '>=16.0.0'} + '@smithy/node-config-provider@4.0.1': + resolution: {integrity: sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==} + engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@3.2.5': resolution: {integrity: sha512-PkOwPNeKdvX/jCpn0A8n9/TyoxjGZB8WVoJmm9YzsnAgggTj4CrjpRHlTQw7dlLZ320n1mY1y+nTRUDViKi/3w==} engines: {node: '>=16.0.0'} + '@smithy/node-http-handler@4.0.2': + resolution: {integrity: sha512-X66H9aah9hisLLSnGuzRYba6vckuFtGE+a5DcHLliI/YlqKrGoxhisD5XbX44KyoeRzoNlGr94eTsMVHFAzPOw==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@3.1.8': resolution: {integrity: sha512-ukNUyo6rHmusG64lmkjFeXemwYuKge1BJ8CtpVKmrxQxc6rhUX0vebcptFA9MmrGsnLhwnnqeH83VTU9hwOpjA==} engines: {node: '>=16.0.0'} + '@smithy/property-provider@4.0.1': + resolution: {integrity: sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ==} + engines: {node: '>=18.0.0'} + '@smithy/protocol-http@4.1.5': resolution: {integrity: sha512-hsjtwpIemmCkm3ZV5fd/T0bPIugW1gJXwZ/hpuVubt2hEUApIoUTrf6qIdh9MAWlw0vjMrA1ztJLAwtNaZogvg==} engines: {node: '>=16.0.0'} + '@smithy/protocol-http@5.0.1': + resolution: {integrity: sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@3.0.8': resolution: {integrity: sha512-btYxGVqFUARbUrN6VhL9c3dnSviIwBYD9Rz1jHuN1hgh28Fpv2xjU1HeCeDJX68xctz7r4l1PBnFhGg1WBBPuA==} engines: {node: '>=16.0.0'} + '@smithy/querystring-builder@4.0.1': + resolution: {integrity: sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@3.0.8': resolution: {integrity: sha512-BtEk3FG7Ks64GAbt+JnKqwuobJNX8VmFLBsKIwWr1D60T426fGrV2L3YS5siOcUhhp6/Y6yhBw1PSPxA5p7qGg==} engines: {node: '>=16.0.0'} + '@smithy/querystring-parser@4.0.1': + resolution: {integrity: sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw==} + engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@3.0.8': resolution: {integrity: sha512-uEC/kCCFto83bz5ZzapcrgGqHOh/0r69sZ2ZuHlgoD5kYgXJEThCoTuw/y1Ub3cE7aaKdznb+jD9xRPIfIwD7g==} engines: {node: '>=16.0.0'} + '@smithy/service-error-classification@4.0.1': + resolution: {integrity: sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA==} + engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@3.1.9': resolution: {integrity: sha512-/+OsJRNtoRbtsX0UpSgWVxFZLsJHo/4sTr+kBg/J78sr7iC+tHeOvOJrS5hCpVQ6sWBbhWLp1UNiuMyZhE6pmA==} engines: {node: '>=16.0.0'} + '@smithy/shared-ini-file-loader@4.0.1': + resolution: {integrity: sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@4.2.1': resolution: {integrity: sha512-NsV1jF4EvmO5wqmaSzlnTVetemBS3FZHdyc5CExbDljcyJCEEkJr8ANu2JvtNbVg/9MvKAWV44kTrGS+Pi4INg==} engines: {node: '>=16.0.0'} + '@smithy/signature-v4@5.0.1': + resolution: {integrity: sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==} + engines: {node: '>=18.0.0'} + '@smithy/smithy-client@3.4.2': resolution: {integrity: sha512-dxw1BDxJiY9/zI3cBqfVrInij6ShjpV4fmGHesGZZUiP9OSE/EVfdwdRz0PgvkEvrZHpsj2htRaHJfftE8giBA==} engines: {node: '>=16.0.0'} + '@smithy/smithy-client@4.1.3': + resolution: {integrity: sha512-A2Hz85pu8BJJaYFdX8yb1yocqigyqBzn+OVaVgm+Kwi/DkN8vhN2kbDVEfADo6jXf5hPKquMLGA3UINA64UZ7A==} + engines: {node: '>=18.0.0'} + + '@smithy/smithy-client@4.1.5': + resolution: {integrity: sha512-DMXYoYeL4QkElr216n1yodTFeATbfb4jwYM9gKn71Rw/FNA1/Sm36tkTSCsZEs7mgpG3OINmkxL9vgVFzyGPaw==} + engines: {node: '>=18.0.0'} + '@smithy/types@3.6.0': resolution: {integrity: sha512-8VXK/KzOHefoC65yRgCn5vG1cysPJjHnOVt9d0ybFQSmJgQj152vMn4EkYhGuaOmnnZvCPav/KnYyE6/KsNZ2w==} engines: {node: '>=16.0.0'} + '@smithy/types@4.1.0': + resolution: {integrity: sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==} + engines: {node: '>=18.0.0'} + '@smithy/url-parser@3.0.8': resolution: {integrity: sha512-4FdOhwpTW7jtSFWm7SpfLGKIBC9ZaTKG5nBF0wK24aoQKQyDIKUw3+KFWCQ9maMzrgTJIuOvOnsV2lLGW5XjTg==} + '@smithy/url-parser@4.0.1': + resolution: {integrity: sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g==} + engines: {node: '>=18.0.0'} + '@smithy/util-base64@3.0.0': resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} engines: {node: '>=16.0.0'} + '@smithy/util-base64@4.0.0': + resolution: {integrity: sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@3.0.0': resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} + '@smithy/util-body-length-browser@4.0.0': + resolution: {integrity: sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@3.0.0': resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} engines: {node: '>=16.0.0'} + '@smithy/util-body-length-node@4.0.0': + resolution: {integrity: sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.0.0': resolution: {integrity: sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==} engines: {node: '>=14.0.0'} @@ -4467,42 +4871,94 @@ packages: resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} engines: {node: '>=16.0.0'} + '@smithy/util-buffer-from@4.0.0': + resolution: {integrity: sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==} + engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@3.0.0': resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} engines: {node: '>=16.0.0'} + '@smithy/util-config-provider@4.0.0': + resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@3.0.25': resolution: {integrity: sha512-fRw7zymjIDt6XxIsLwfJfYUfbGoO9CmCJk6rjJ/X5cd20+d2Is7xjU5Kt/AiDt6hX8DAf5dztmfP5O82gR9emA==} engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-browser@4.0.4': + resolution: {integrity: sha512-Ej1bV5sbrIfH++KnWxjjzFNq9nyP3RIUq2c9Iqq7SmMO/idUR24sqvKH2LUQFTSPy/K7G4sB2m8n7YYlEAfZaw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-browser@4.0.6': + resolution: {integrity: sha512-N8+VCt+piupH1A7DgSVDNrVHqRLz8r6DvBkpS7EWHiIxsUk4jqGuQLjqC/gnCzmwGkVBdNruHoYAzzaSQ8e80w==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@3.0.25': resolution: {integrity: sha512-H3BSZdBDiVZGzt8TG51Pd2FvFO0PAx/A0mJ0EH8a13KJ6iUCdYnw/Dk/MdC1kTd0eUuUGisDFaxXVXo4HHFL1g==} engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-node@4.0.4': + resolution: {integrity: sha512-HE1I7gxa6yP7ZgXPCFfZSDmVmMtY7SHqzFF55gM/GPegzZKaQWZZ+nYn9C2Cc3JltCMyWe63VPR3tSFDEvuGjw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-node@4.0.6': + resolution: {integrity: sha512-9zhx1shd1VwSSVvLZB8CM3qQ3RPD3le7A3h/UPuyh/PC7g4OaWDi2xUNzamsVoSmCGtmUBONl56lM2EU6LcH7A==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@2.1.4': resolution: {integrity: sha512-kPt8j4emm7rdMWQyL0F89o92q10gvCUa6sBkBtDJ7nV2+P7wpXczzOfoDJ49CKXe5CCqb8dc1W+ZdLlrKzSAnQ==} engines: {node: '>=16.0.0'} + '@smithy/util-endpoints@3.0.1': + resolution: {integrity: sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA==} + engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@3.0.0': resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} engines: {node: '>=16.0.0'} + '@smithy/util-hex-encoding@4.0.0': + resolution: {integrity: sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@3.0.8': resolution: {integrity: sha512-p7iYAPaQjoeM+AKABpYWeDdtwQNxasr4aXQEA/OmbOaug9V0odRVDy3Wx4ci8soljE/JXQo+abV0qZpW8NX0yA==} engines: {node: '>=16.0.0'} + '@smithy/util-middleware@4.0.1': + resolution: {integrity: sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA==} + engines: {node: '>=18.0.0'} + '@smithy/util-retry@3.0.8': resolution: {integrity: sha512-TCEhLnY581YJ+g1x0hapPz13JFqzmh/pMWL2KEFASC51qCfw3+Y47MrTmea4bUE5vsdxQ4F6/KFbUeSz22Q1ow==} engines: {node: '>=16.0.0'} + '@smithy/util-retry@4.0.1': + resolution: {integrity: sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==} + engines: {node: '>=18.0.0'} + '@smithy/util-stream@3.2.1': resolution: {integrity: sha512-R3ufuzJRxSJbE58K9AEnL/uSZyVdHzud9wLS8tIbXclxKzoe09CRohj2xV8wpx5tj7ZbiJaKYcutMm1eYgz/0A==} engines: {node: '>=16.0.0'} + '@smithy/util-stream@4.0.2': + resolution: {integrity: sha512-0eZ4G5fRzIoewtHtwaYyl8g2C+osYOT4KClXgfdNEDAgkbe2TYPqcnw4GAWabqkZCax2ihRGPe9LZnsPdIUIHA==} + engines: {node: '>=18.0.0'} + + '@smithy/util-stream@4.1.1': + resolution: {integrity: sha512-+Xvh8nhy0Wjv1y71rBVyV3eJU3356XsFQNI8dEZVNrQju7Eib8G31GWtO+zMa9kTCGd41Mflu+ZKfmQL/o2XzQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@3.0.0': resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} engines: {node: '>=16.0.0'} + '@smithy/util-uri-escape@4.0.0': + resolution: {integrity: sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==} + engines: {node: '>=18.0.0'} + '@smithy/util-utf8@2.0.0': resolution: {integrity: sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==} engines: {node: '>=14.0.0'} @@ -4511,10 +4967,18 @@ packages: resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} engines: {node: '>=16.0.0'} + '@smithy/util-utf8@4.0.0': + resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==} + engines: {node: '>=18.0.0'} + '@smithy/util-waiter@3.1.7': resolution: {integrity: sha512-d5yGlQtmN/z5eoTtIYgkvOw27US2Ous4VycnXatyoImIF9tzlcpnKqQ/V7qhvJmb2p6xZne1NopCLakdTnkBBQ==} engines: {node: '>=16.0.0'} + '@smithy/util-waiter@4.0.2': + resolution: {integrity: sha512-piUTHyp2Axx3p/kc2CIJkYSv0BAaheBQmbACZgQSSfWUumWNW+R1lL+H9PDBxKJkvOeEX+hKYEFiwO8xagL8AQ==} + engines: {node: '>=18.0.0'} + '@solid-primitives/event-listener@2.3.3': resolution: {integrity: sha512-DAJbl+F0wrFW2xmcV8dKMBhk9QLVLuBSW+TR4JmIfTaObxd13PuL7nqaXnaYKDWOYa6otB00qcCUIGbuIhSUgQ==} peerDependencies: @@ -4759,6 +5223,9 @@ packages: '@types/acorn@4.0.6': resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + '@types/aws-lambda@8.10.147': + resolution: {integrity: sha512-nD0Z9fNIZcxYX5Mai2CTmFD7wX7UldCkW2ezCF8D1T5hdiLsnTWDGRpfRYntU6VjTdLQjOvyszru7I1c1oCQew==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -4868,6 +5335,9 @@ packages: '@types/node@22.13.0': resolution: {integrity: sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==} + '@types/node@22.13.1': + resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==} + '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} @@ -4922,6 +5392,12 @@ packages: '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + '@types/sinon@17.0.4': + resolution: {integrity: sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==} + + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} @@ -5530,6 +6006,17 @@ packages: avvio@8.3.0: resolution: {integrity: sha512-VBVH0jubFr9LdFASy/vNtm5giTrnbVquWBhT0fyizuNK2rQ7e7ONU2plZQWUNqtE1EmxFEb+kbSkFRkstiaS9Q==} + aws-lambda@1.0.7: + resolution: {integrity: sha512-9GNFMRrEMG5y3Jvv+V4azWvc+qNWdWLTjDdhf/zgMlz8haaaLWv0xeAIWxz9PuWUBawsVxy0zZotjCdR3Xq+2w==} + hasBin: true + + aws-sdk-client-mock@4.1.0: + resolution: {integrity: sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==} + + aws-sdk@2.1692.0: + resolution: {integrity: sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==} + engines: {node: '>= 10.0.0'} + axios@1.7.7: resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} @@ -5733,6 +6220,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + buffer@5.6.0: resolution: {integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==} @@ -5764,10 +6254,18 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + caller-callsite@2.0.0: resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} engines: {node: '>=4'} @@ -6014,6 +6512,9 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -6390,6 +6891,10 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -6490,6 +6995,10 @@ packages: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} engines: {node: '>= 0.4'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} @@ -6519,6 +7028,9 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} + es-toolkit@1.32.0: + resolution: {integrity: sha512-ZfSfHP1l6ubgW/B/FRtqb9bYdMvI6jizbOSfbwwJNcOQ1QE6TFsC3jpQkZ900uUPSR3t3SU5Ds7UWKnYz+uP8Q==} + esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -6716,6 +7228,10 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + events@1.1.1: + resolution: {integrity: sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==} + engines: {node: '>=0.4.x'} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -7027,10 +7543,18 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + engines: {node: '>= 0.4'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} @@ -7118,6 +7642,10 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -7153,6 +7681,10 @@ packages: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} @@ -7351,6 +7883,9 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + ieee754@1.1.13: + resolution: {integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -7452,6 +7987,10 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -7926,6 +8465,10 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + jmespath@0.16.0: + resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} + engines: {node: '>= 0.6.0'} + joi@17.11.0: resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} @@ -8030,6 +8573,9 @@ packages: jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + just-extend@6.2.0: + resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} + jwa@1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} @@ -8127,6 +8673,10 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -8230,6 +8780,10 @@ packages: marky@1.2.5: resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-definitions@5.1.2: resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} @@ -8758,6 +9312,9 @@ packages: nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + nise@6.1.1: + resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} + nocache@3.0.4: resolution: {integrity: sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==} engines: {node: '>=12.0.0'} @@ -9102,6 +9659,10 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -9427,6 +9988,9 @@ packages: pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + punycode@1.3.2: + resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -9438,6 +10002,11 @@ packages: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} + querystring@0.2.0: + resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} + engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. + querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} @@ -10043,6 +10612,9 @@ packages: engines: {node: '>=16.0.0'} hasBin: true + sax@1.2.1: + resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==} + saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -10194,6 +10766,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + sinon@18.0.1: + resolution: {integrity: sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -10737,6 +11312,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -10933,6 +11512,9 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + url@0.10.3: + resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} + use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -10941,10 +11523,17 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@8.0.0: + resolution: {integrity: sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -11435,6 +12024,14 @@ packages: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} @@ -11527,13 +12124,13 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.679.0 + '@aws-sdk/types': 3.734.0 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.679.0 + '@aws-sdk/types': 3.734.0 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': @@ -11550,7 +12147,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.679.0 + '@aws-sdk/types': 3.734.0 '@aws-sdk/util-locate-window': 3.310.0 '@smithy/util-utf8': 2.0.0 tslib: 2.8.1 @@ -11558,7 +12155,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.679.0 + '@aws-sdk/types': 3.734.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -11567,10 +12164,195 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.679.0 + '@aws-sdk/types': 3.734.0 '@smithy/util-utf8': 2.0.0 tslib: 2.8.1 + '@aws-sdk/client-cloudfront@3.745.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/credential-provider-node': 3.744.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.744.0 + '@aws-sdk/xml-builder': 3.734.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.2 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-retry': 4.0.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.4 + '@smithy/util-defaults-mode-node': 4.0.4 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-stream': 4.0.2 + '@smithy/util-utf8': 4.0.0 + '@smithy/util-waiter': 4.0.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-cognito-identity@3.744.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/credential-provider-node': 3.744.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.744.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.2 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-retry': 4.0.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.4 + '@smithy/util-defaults-mode-node': 4.0.4 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-iam@3.749.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.749.0 + '@aws-sdk/credential-provider-node': 3.749.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.749.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.749.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.4 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.5 + '@smithy/middleware-retry': 4.0.6 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.6 + '@smithy/util-defaults-mode-node': 4.0.6 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + '@smithy/util-waiter': 4.0.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-lambda@3.744.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/credential-provider-node': 3.744.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.744.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.2 + '@smithy/eventstream-serde-browser': 4.0.1 + '@smithy/eventstream-serde-config-resolver': 4.0.1 + '@smithy/eventstream-serde-node': 4.0.1 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-retry': 4.0.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.4 + '@smithy/util-defaults-mode-node': 4.0.4 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-stream': 4.0.2 + '@smithy/util-utf8': 4.0.0 + '@smithy/util-waiter': 4.0.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/client-s3@3.685.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 @@ -11722,6 +12504,92 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/client-sso@3.744.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.744.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.2 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-retry': 4.0.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.4 + '@smithy/util-defaults-mode-node': 4.0.4 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso@3.749.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.749.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.749.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.749.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.4 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.5 + '@smithy/middleware-retry': 4.0.6 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.6 + '@smithy/util-defaults-mode-node': 4.0.6 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/client-sts@3.682.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 @@ -11781,6 +12649,58 @@ snapshots: fast-xml-parser: 4.4.1 tslib: 2.8.1 + '@aws-sdk/core@3.744.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/core': 3.1.2 + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/signature-v4': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/util-middleware': 4.0.1 + fast-xml-parser: 4.4.1 + tslib: 2.8.1 + + '@aws-sdk/core@3.749.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/core': 3.1.4 + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/signature-v4': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/util-middleware': 4.0.1 + fast-xml-parser: 4.4.1 + tslib: 2.8.1 + + '@aws-sdk/core@3.750.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/core': 3.1.4 + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/signature-v4': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/util-middleware': 4.0.1 + fast-xml-parser: 4.4.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-cognito-identity@3.744.0': + dependencies: + '@aws-sdk/client-cognito-identity': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-env@3.679.0': dependencies: '@aws-sdk/core': 3.679.0 @@ -11789,11 +12709,27 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.679.0': + '@aws-sdk/credential-provider-env@3.744.0': dependencies: - '@aws-sdk/core': 3.679.0 - '@aws-sdk/types': 3.679.0 - '@smithy/fetch-http-handler': 3.2.9 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.679.0': + dependencies: + '@aws-sdk/core': 3.679.0 + '@aws-sdk/types': 3.679.0 + '@smithy/fetch-http-handler': 3.2.9 '@smithy/node-http-handler': 3.2.5 '@smithy/property-provider': 3.1.8 '@smithy/protocol-http': 4.1.5 @@ -11802,6 +12738,32 @@ snapshots: '@smithy/util-stream': 3.2.1 tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.744.0': + dependencies: + '@aws-sdk/core': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/property-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/util-stream': 4.0.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/property-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/util-stream': 4.1.1 + tslib: 2.8.1 + '@aws-sdk/credential-provider-ini@3.682.0(@aws-sdk/client-sso-oidc@3.682.0(@aws-sdk/client-sts@3.682.0))(@aws-sdk/client-sts@3.682.0)': dependencies: '@aws-sdk/client-sts': 3.682.0 @@ -11821,6 +12783,42 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt + '@aws-sdk/credential-provider-ini@3.744.0': + dependencies: + '@aws-sdk/core': 3.744.0 + '@aws-sdk/credential-provider-env': 3.744.0 + '@aws-sdk/credential-provider-http': 3.744.0 + '@aws-sdk/credential-provider-process': 3.744.0 + '@aws-sdk/credential-provider-sso': 3.744.0 + '@aws-sdk/credential-provider-web-identity': 3.744.0 + '@aws-sdk/nested-clients': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-ini@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/credential-provider-env': 3.749.0 + '@aws-sdk/credential-provider-http': 3.749.0 + '@aws-sdk/credential-provider-process': 3.749.0 + '@aws-sdk/credential-provider-sso': 3.749.0 + '@aws-sdk/credential-provider-web-identity': 3.749.0 + '@aws-sdk/nested-clients': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-node@3.682.0(@aws-sdk/client-sso-oidc@3.682.0(@aws-sdk/client-sts@3.682.0))(@aws-sdk/client-sts@3.682.0)': dependencies: '@aws-sdk/credential-provider-env': 3.679.0 @@ -11840,6 +12838,40 @@ snapshots: - '@aws-sdk/client-sts' - aws-crt + '@aws-sdk/credential-provider-node@3.744.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.744.0 + '@aws-sdk/credential-provider-http': 3.744.0 + '@aws-sdk/credential-provider-ini': 3.744.0 + '@aws-sdk/credential-provider-process': 3.744.0 + '@aws-sdk/credential-provider-sso': 3.744.0 + '@aws-sdk/credential-provider-web-identity': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.749.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.749.0 + '@aws-sdk/credential-provider-http': 3.749.0 + '@aws-sdk/credential-provider-ini': 3.749.0 + '@aws-sdk/credential-provider-process': 3.749.0 + '@aws-sdk/credential-provider-sso': 3.749.0 + '@aws-sdk/credential-provider-web-identity': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-process@3.679.0': dependencies: '@aws-sdk/core': 3.679.0 @@ -11849,6 +12881,24 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-process@3.744.0': + dependencies: + '@aws-sdk/core': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-sso@3.682.0(@aws-sdk/client-sso-oidc@3.682.0(@aws-sdk/client-sts@3.682.0))': dependencies: '@aws-sdk/client-sso': 3.682.0 @@ -11863,6 +12913,32 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt + '@aws-sdk/credential-provider-sso@3.744.0': + dependencies: + '@aws-sdk/client-sso': 3.744.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/token-providers': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-sso@3.749.0': + dependencies: + '@aws-sdk/client-sso': 3.749.0 + '@aws-sdk/core': 3.749.0 + '@aws-sdk/token-providers': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-web-identity@3.679.0(@aws-sdk/client-sts@3.682.0)': dependencies: '@aws-sdk/client-sts': 3.682.0 @@ -11872,6 +12948,50 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-web-identity@3.744.0': + dependencies: + '@aws-sdk/core': 3.744.0 + '@aws-sdk/nested-clients': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/nested-clients': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-providers@3.744.0': + dependencies: + '@aws-sdk/client-cognito-identity': 3.744.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/credential-provider-cognito-identity': 3.744.0 + '@aws-sdk/credential-provider-env': 3.744.0 + '@aws-sdk/credential-provider-http': 3.744.0 + '@aws-sdk/credential-provider-ini': 3.744.0 + '@aws-sdk/credential-provider-node': 3.744.0 + '@aws-sdk/credential-provider-process': 3.744.0 + '@aws-sdk/credential-provider-sso': 3.744.0 + '@aws-sdk/credential-provider-web-identity': 3.744.0 + '@aws-sdk/nested-clients': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/core': 3.1.2 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/lib-storage@3.685.0(@aws-sdk/client-s3@3.685.0)': dependencies: '@aws-sdk/client-s3': 3.685.0 @@ -11921,6 +13041,13 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/middleware-host-header@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/middleware-location-constraint@3.679.0': dependencies: '@aws-sdk/types': 3.679.0 @@ -11933,6 +13060,12 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/middleware-logger@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.679.0': dependencies: '@aws-sdk/types': 3.679.0 @@ -11940,6 +13073,13 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/middleware-sdk-s3@3.685.0': dependencies: '@aws-sdk/core': 3.679.0 @@ -11957,6 +13097,23 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@aws-sdk/middleware-sdk-s3@3.750.0': + dependencies: + '@aws-sdk/core': 3.750.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-arn-parser': 3.723.0 + '@smithy/core': 3.1.4 + '@smithy/node-config-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/signature-v4': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/util-config-provider': 4.0.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-stream': 4.1.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@aws-sdk/middleware-ssec@3.679.0': dependencies: '@aws-sdk/types': 3.679.0 @@ -11973,6 +13130,112 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/middleware-user-agent@3.744.0': + dependencies: + '@aws-sdk/core': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@smithy/core': 3.1.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-user-agent@3.749.0': + dependencies: + '@aws-sdk/core': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@smithy/core': 3.1.4 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.744.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.744.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.744.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.2 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-retry': 4.0.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.4 + '@smithy/util-defaults-mode-node': 4.0.4 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/nested-clients@3.749.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.749.0 + '@aws-sdk/middleware-host-header': 3.734.0 + '@aws-sdk/middleware-logger': 3.734.0 + '@aws-sdk/middleware-recursion-detection': 3.734.0 + '@aws-sdk/middleware-user-agent': 3.749.0 + '@aws-sdk/region-config-resolver': 3.734.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-endpoints': 3.743.0 + '@aws-sdk/util-user-agent-browser': 3.734.0 + '@aws-sdk/util-user-agent-node': 3.749.0 + '@smithy/config-resolver': 4.0.1 + '@smithy/core': 3.1.4 + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/hash-node': 4.0.1 + '@smithy/invalid-dependency': 4.0.1 + '@smithy/middleware-content-length': 4.0.1 + '@smithy/middleware-endpoint': 4.0.5 + '@smithy/middleware-retry': 4.0.6 + '@smithy/middleware-serde': 4.0.2 + '@smithy/middleware-stack': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-base64': 4.0.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-body-length-node': 4.0.0 + '@smithy/util-defaults-mode-browser': 4.0.6 + '@smithy/util-defaults-mode-node': 4.0.6 + '@smithy/util-endpoints': 3.0.1 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/region-config-resolver@3.679.0': dependencies: '@aws-sdk/types': 3.679.0 @@ -11982,6 +13245,26 @@ snapshots: '@smithy/util-middleware': 3.0.8 tslib: 2.8.1 + '@aws-sdk/region-config-resolver@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/node-config-provider': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-config-provider': 4.0.0 + '@smithy/util-middleware': 4.0.1 + tslib: 2.8.1 + + '@aws-sdk/s3-request-presigner@3.750.0': + dependencies: + '@aws-sdk/signature-v4-multi-region': 3.750.0 + '@aws-sdk/types': 3.734.0 + '@aws-sdk/util-format-url': 3.734.0 + '@smithy/middleware-endpoint': 4.0.5 + '@smithy/protocol-http': 5.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/signature-v4-multi-region@3.685.0': dependencies: '@aws-sdk/middleware-sdk-s3': 3.685.0 @@ -11991,6 +13274,15 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/signature-v4-multi-region@3.750.0': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.750.0 + '@aws-sdk/types': 3.734.0 + '@smithy/protocol-http': 5.0.1 + '@smithy/signature-v4': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/token-providers@3.679.0(@aws-sdk/client-sso-oidc@3.682.0(@aws-sdk/client-sts@3.682.0))': dependencies: '@aws-sdk/client-sso-oidc': 3.682.0(@aws-sdk/client-sts@3.682.0) @@ -12000,15 +13292,46 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/token-providers@3.744.0': + dependencies: + '@aws-sdk/nested-clients': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/token-providers@3.749.0': + dependencies: + '@aws-sdk/nested-clients': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/types@3.679.0': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/types@3.734.0': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/util-arn-parser@3.679.0': dependencies: tslib: 2.8.1 + '@aws-sdk/util-arn-parser@3.723.0': + dependencies: + tslib: 2.8.1 + '@aws-sdk/util-endpoints@3.679.0': dependencies: '@aws-sdk/types': 3.679.0 @@ -12016,6 +13339,20 @@ snapshots: '@smithy/util-endpoints': 2.1.4 tslib: 2.8.1 + '@aws-sdk/util-endpoints@3.743.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/types': 4.1.0 + '@smithy/util-endpoints': 3.0.1 + tslib: 2.8.1 + + '@aws-sdk/util-format-url@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/querystring-builder': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/util-locate-window@3.310.0': dependencies: tslib: 2.8.1 @@ -12027,6 +13364,13 @@ snapshots: bowser: 2.11.0 tslib: 2.8.1 + '@aws-sdk/util-user-agent-browser@3.734.0': + dependencies: + '@aws-sdk/types': 3.734.0 + '@smithy/types': 4.1.0 + bowser: 2.11.0 + tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.682.0': dependencies: '@aws-sdk/middleware-user-agent': 3.682.0 @@ -12035,11 +13379,32 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.744.0': + dependencies: + '@aws-sdk/middleware-user-agent': 3.744.0 + '@aws-sdk/types': 3.734.0 + '@smithy/node-config-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-node@3.749.0': + dependencies: + '@aws-sdk/middleware-user-agent': 3.749.0 + '@aws-sdk/types': 3.734.0 + '@smithy/node-config-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@aws-sdk/xml-builder@3.679.0': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@aws-sdk/xml-builder@3.734.0': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -14082,6 +15447,14 @@ snapshots: '@types/node': 22.13.0 optional: true + '@inquirer/confirm@5.1.6(@types/node@22.13.1)': + dependencies: + '@inquirer/core': 10.1.7(@types/node@22.13.1) + '@inquirer/type': 3.0.4(@types/node@22.13.1) + optionalDependencies: + '@types/node': 22.13.1 + optional: true + '@inquirer/core@10.1.7(@types/node@20.16.10)': dependencies: '@inquirer/figures': 1.0.10 @@ -14109,6 +15482,20 @@ snapshots: '@types/node': 22.13.0 optional: true + '@inquirer/core@10.1.7(@types/node@22.13.1)': + dependencies: + '@inquirer/figures': 1.0.10 + '@inquirer/type': 3.0.4(@types/node@22.13.1) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.13.1 + optional: true + '@inquirer/figures@1.0.10': {} '@inquirer/type@3.0.4(@types/node@20.16.10)': @@ -14120,6 +15507,11 @@ snapshots: '@types/node': 22.13.0 optional: true + '@inquirer/type@3.0.4(@types/node@22.13.1)': + optionalDependencies: + '@types/node': 22.13.1 + optional: true + '@internationalized/date@3.5.6': dependencies: '@swc/helpers': 0.5.13 @@ -14228,7 +15620,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -14242,7 +15634,42 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -14599,7 +16026,7 @@ snapshots: tslib: 2.8.1 yargs-parser: 21.1.1 - '@nx/js@20.3.0(@babel/traverse@7.25.9)(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(nx@20.3.0(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15)))(typescript@5.7.2)': + '@nx/js@20.3.0(@babel/traverse@7.25.9)(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(nx@20.3.0(@swc-node/register@1.10.9(@swc/core@1.7.42(@swc/helpers@0.5.15))(@swc/types@0.1.13)(typescript@5.7.2))(@swc/core@1.7.42(@swc/helpers@0.5.15)))(typescript@5.7.2)': dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -14628,7 +16055,7 @@ snapshots: semver: 7.6.3 source-map-support: 0.5.19 tinyglobby: 0.2.10 - ts-node: 10.9.1(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2) + ts-node: 10.9.1(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2) tsconfig-paths: 4.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -15949,7 +17376,7 @@ snapshots: - supports-color - utf-8-validate - '@react-native/eslint-config@0.74.83(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)))(prettier@2.8.8)(typescript@5.7.2)': + '@react-native/eslint-config@0.74.83(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)))(prettier@2.8.8)(typescript@5.7.2)': dependencies: '@babel/core': 7.26.0 '@babel/eslint-parser': 7.24.5(@babel/core@7.26.0)(eslint@8.57.0) @@ -15960,7 +17387,7 @@ snapshots: eslint-config-prettier: 8.10.0(eslint@8.57.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) eslint-plugin-ft-flow: 2.0.3(@babel/eslint-parser@7.24.5(@babel/core@7.26.0)(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-jest: 26.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)))(typescript@5.7.2) + eslint-plugin-jest: 26.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)))(typescript@5.7.2) eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -15971,7 +17398,7 @@ snapshots: - supports-color - typescript - '@react-native/eslint-config@0.76.1(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4)': + '@react-native/eslint-config@0.76.1(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4)': dependencies: '@babel/core': 7.26.0 '@babel/eslint-parser': 7.25.9(@babel/core@7.26.0)(eslint@8.57.0) @@ -15982,7 +17409,7 @@ snapshots: eslint-config-prettier: 8.10.0(eslint@8.57.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) eslint-plugin-ft-flow: 2.0.3(@babel/eslint-parser@7.25.9(@babel/core@7.26.0)(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)))(typescript@5.0.4) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)))(typescript@5.0.4) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) eslint-plugin-react-native: 4.1.0(eslint@8.57.0) @@ -16638,15 +18065,40 @@ snapshots: dependencies: type-detect: 4.0.8 + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + '@sinonjs/fake-timers@10.3.0': dependencies: '@sinonjs/commons': 3.0.0 + '@sinonjs/fake-timers@11.2.2': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/fake-timers@13.0.5': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/samsam@8.0.2': + dependencies: + '@sinonjs/commons': 3.0.1 + lodash.get: 4.4.2 + type-detect: 4.1.0 + + '@sinonjs/text-encoding@0.7.3': {} + '@smithy/abort-controller@3.1.6': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/abort-controller@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/chunked-blob-reader-native@3.0.1': dependencies: '@smithy/util-base64': 3.0.0 @@ -16664,6 +18116,14 @@ snapshots: '@smithy/util-middleware': 3.0.8 tslib: 2.8.1 + '@smithy/config-resolver@4.0.1': + dependencies: + '@smithy/node-config-provider': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-config-provider': 4.0.0 + '@smithy/util-middleware': 4.0.1 + tslib: 2.8.1 + '@smithy/core@2.5.1': dependencies: '@smithy/middleware-serde': 3.0.8 @@ -16675,6 +18135,28 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@smithy/core@3.1.2': + dependencies: + '@smithy/middleware-serde': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-stream': 4.0.2 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + + '@smithy/core@3.1.4': + dependencies: + '@smithy/middleware-serde': 4.0.2 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-body-length-browser': 4.0.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-stream': 4.1.1 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@smithy/credential-provider-imds@3.2.5': dependencies: '@smithy/node-config-provider': 3.1.9 @@ -16683,6 +18165,14 @@ snapshots: '@smithy/url-parser': 3.0.8 tslib: 2.8.1 + '@smithy/credential-provider-imds@4.0.1': + dependencies: + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + tslib: 2.8.1 + '@smithy/eventstream-codec@3.1.7': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -16690,29 +18180,59 @@ snapshots: '@smithy/util-hex-encoding': 3.0.0 tslib: 2.8.1 + '@smithy/eventstream-codec@4.0.1': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.1.0 + '@smithy/util-hex-encoding': 4.0.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-browser@3.0.11': dependencies: '@smithy/eventstream-serde-universal': 3.0.10 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/eventstream-serde-browser@4.0.1': + dependencies: + '@smithy/eventstream-serde-universal': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-config-resolver@3.0.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/eventstream-serde-config-resolver@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-node@3.0.10': dependencies: '@smithy/eventstream-serde-universal': 3.0.10 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/eventstream-serde-node@4.0.1': + dependencies: + '@smithy/eventstream-serde-universal': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-universal@3.0.10': dependencies: '@smithy/eventstream-codec': 3.1.7 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/eventstream-serde-universal@4.0.1': + dependencies: + '@smithy/eventstream-codec': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/fetch-http-handler@3.2.9': dependencies: '@smithy/protocol-http': 4.1.5 @@ -16729,6 +18249,14 @@ snapshots: '@smithy/util-base64': 3.0.0 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.0.1': + dependencies: + '@smithy/protocol-http': 5.0.1 + '@smithy/querystring-builder': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-base64': 4.0.0 + tslib: 2.8.1 + '@smithy/hash-blob-browser@3.1.7': dependencies: '@smithy/chunked-blob-reader': 4.0.0 @@ -16743,6 +18271,13 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@smithy/hash-node@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@smithy/hash-stream-node@3.1.7': dependencies: '@smithy/types': 3.6.0 @@ -16754,6 +18289,11 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/invalid-dependency@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/is-array-buffer@2.0.0': dependencies: tslib: 2.8.1 @@ -16762,6 +18302,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/is-array-buffer@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/md5-js@3.0.8': dependencies: '@smithy/types': 3.6.0 @@ -16774,6 +18318,12 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/middleware-content-length@4.0.1': + dependencies: + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/middleware-endpoint@3.2.1': dependencies: '@smithy/core': 2.5.1 @@ -16785,6 +18335,28 @@ snapshots: '@smithy/util-middleware': 3.0.8 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.0.3': + dependencies: + '@smithy/core': 3.1.2 + '@smithy/middleware-serde': 4.0.2 + '@smithy/node-config-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-middleware': 4.0.1 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.0.5': + dependencies: + '@smithy/core': 3.1.4 + '@smithy/middleware-serde': 4.0.2 + '@smithy/node-config-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + '@smithy/url-parser': 4.0.1 + '@smithy/util-middleware': 4.0.1 + tslib: 2.8.1 + '@smithy/middleware-retry@3.0.25': dependencies: '@smithy/node-config-provider': 3.1.9 @@ -16797,16 +18369,50 @@ snapshots: tslib: 2.8.1 uuid: 9.0.1 + '@smithy/middleware-retry@4.0.4': + dependencies: + '@smithy/node-config-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/service-error-classification': 4.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + tslib: 2.8.1 + uuid: 9.0.1 + + '@smithy/middleware-retry@4.0.6': + dependencies: + '@smithy/node-config-provider': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/service-error-classification': 4.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-retry': 4.0.1 + tslib: 2.8.1 + uuid: 9.0.1 + '@smithy/middleware-serde@3.0.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/middleware-serde@4.0.2': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/middleware-stack@3.0.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/middleware-stack@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/node-config-provider@3.1.9': dependencies: '@smithy/property-provider': 3.1.8 @@ -16814,6 +18420,13 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/node-config-provider@4.0.1': + dependencies: + '@smithy/property-provider': 4.0.1 + '@smithy/shared-ini-file-loader': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/node-http-handler@3.2.5': dependencies: '@smithy/abort-controller': 3.1.6 @@ -16822,36 +18435,74 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/node-http-handler@4.0.2': + dependencies: + '@smithy/abort-controller': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/querystring-builder': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/property-provider@3.1.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/property-provider@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/protocol-http@4.1.5': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/protocol-http@5.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/querystring-builder@3.0.8': dependencies: '@smithy/types': 3.6.0 '@smithy/util-uri-escape': 3.0.0 tslib: 2.8.1 + '@smithy/querystring-builder@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + '@smithy/util-uri-escape': 4.0.0 + tslib: 2.8.1 + '@smithy/querystring-parser@3.0.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/querystring-parser@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/service-error-classification@3.0.8': dependencies: '@smithy/types': 3.6.0 + '@smithy/service-error-classification@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + '@smithy/shared-ini-file-loader@3.1.9': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/signature-v4@4.2.1': dependencies: '@smithy/is-array-buffer': 3.0.0 @@ -16863,6 +18514,17 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@smithy/signature-v4@5.0.1': + dependencies: + '@smithy/is-array-buffer': 4.0.0 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-hex-encoding': 4.0.0 + '@smithy/util-middleware': 4.0.1 + '@smithy/util-uri-escape': 4.0.0 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@smithy/smithy-client@3.4.2': dependencies: '@smithy/core': 2.5.1 @@ -16873,30 +18535,74 @@ snapshots: '@smithy/util-stream': 3.2.1 tslib: 2.8.1 + '@smithy/smithy-client@4.1.3': + dependencies: + '@smithy/core': 3.1.2 + '@smithy/middleware-endpoint': 4.0.3 + '@smithy/middleware-stack': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-stream': 4.0.2 + tslib: 2.8.1 + + '@smithy/smithy-client@4.1.5': + dependencies: + '@smithy/core': 3.1.4 + '@smithy/middleware-endpoint': 4.0.5 + '@smithy/middleware-stack': 4.0.1 + '@smithy/protocol-http': 5.0.1 + '@smithy/types': 4.1.0 + '@smithy/util-stream': 4.1.1 + tslib: 2.8.1 + '@smithy/types@3.6.0': dependencies: tslib: 2.8.1 + '@smithy/types@4.1.0': + dependencies: + tslib: 2.8.1 + '@smithy/url-parser@3.0.8': dependencies: '@smithy/querystring-parser': 3.0.8 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/url-parser@4.0.1': + dependencies: + '@smithy/querystring-parser': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/util-base64@3.0.0': dependencies: '@smithy/util-buffer-from': 3.0.0 '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@smithy/util-base64@4.0.0': + dependencies: + '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@smithy/util-body-length-browser@3.0.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-browser@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/util-body-length-node@3.0.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-node@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/util-buffer-from@2.0.0': dependencies: '@smithy/is-array-buffer': 2.0.0 @@ -16907,10 +18613,19 @@ snapshots: '@smithy/is-array-buffer': 3.0.0 tslib: 2.8.1 + '@smithy/util-buffer-from@4.0.0': + dependencies: + '@smithy/is-array-buffer': 4.0.0 + tslib: 2.8.1 + '@smithy/util-config-provider@3.0.0': dependencies: tslib: 2.8.1 + '@smithy/util-config-provider@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@3.0.25': dependencies: '@smithy/property-provider': 3.1.8 @@ -16919,6 +18634,22 @@ snapshots: bowser: 2.11.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.0.4': + dependencies: + '@smithy/property-provider': 4.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + bowser: 2.11.0 + tslib: 2.8.1 + + '@smithy/util-defaults-mode-browser@4.0.6': + dependencies: + '@smithy/property-provider': 4.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + bowser: 2.11.0 + tslib: 2.8.1 + '@smithy/util-defaults-mode-node@3.0.25': dependencies: '@smithy/config-resolver': 3.0.10 @@ -16929,27 +18660,68 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.0.4': + dependencies: + '@smithy/config-resolver': 4.0.1 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/smithy-client': 4.1.3 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + + '@smithy/util-defaults-mode-node@4.0.6': + dependencies: + '@smithy/config-resolver': 4.0.1 + '@smithy/credential-provider-imds': 4.0.1 + '@smithy/node-config-provider': 4.0.1 + '@smithy/property-provider': 4.0.1 + '@smithy/smithy-client': 4.1.5 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/util-endpoints@2.1.4': dependencies: '@smithy/node-config-provider': 3.1.9 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/util-endpoints@3.0.1': + dependencies: + '@smithy/node-config-provider': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/util-hex-encoding@3.0.0': dependencies: tslib: 2.8.1 + '@smithy/util-hex-encoding@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/util-middleware@3.0.8': dependencies: '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/util-middleware@4.0.1': + dependencies: + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/util-retry@3.0.8': dependencies: '@smithy/service-error-classification': 3.0.8 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/util-retry@4.0.1': + dependencies: + '@smithy/service-error-classification': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@smithy/util-stream@3.2.1': dependencies: '@smithy/fetch-http-handler': 4.0.0 @@ -16961,10 +18733,36 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.8.1 + '@smithy/util-stream@4.0.2': + dependencies: + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/types': 4.1.0 + '@smithy/util-base64': 4.0.0 + '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-hex-encoding': 4.0.0 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + + '@smithy/util-stream@4.1.1': + dependencies: + '@smithy/fetch-http-handler': 5.0.1 + '@smithy/node-http-handler': 4.0.2 + '@smithy/types': 4.1.0 + '@smithy/util-base64': 4.0.0 + '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-hex-encoding': 4.0.0 + '@smithy/util-utf8': 4.0.0 + tslib: 2.8.1 + '@smithy/util-uri-escape@3.0.0': dependencies: tslib: 2.8.1 + '@smithy/util-uri-escape@4.0.0': + dependencies: + tslib: 2.8.1 + '@smithy/util-utf8@2.0.0': dependencies: '@smithy/util-buffer-from': 2.0.0 @@ -16975,12 +18773,23 @@ snapshots: '@smithy/util-buffer-from': 3.0.0 tslib: 2.8.1 + '@smithy/util-utf8@4.0.0': + dependencies: + '@smithy/util-buffer-from': 4.0.0 + tslib: 2.8.1 + '@smithy/util-waiter@3.1.7': dependencies: '@smithy/abort-controller': 3.1.6 '@smithy/types': 3.6.0 tslib: 2.8.1 + '@smithy/util-waiter@4.0.2': + dependencies: + '@smithy/abort-controller': 4.0.1 + '@smithy/types': 4.1.0 + tslib: 2.8.1 + '@solid-primitives/event-listener@2.3.3(solid-js@1.9.3)': dependencies: '@solid-primitives/utils': 6.2.3(solid-js@1.9.3) @@ -17236,6 +19045,8 @@ snapshots: dependencies: '@types/estree': 1.0.6 + '@types/aws-lambda@8.10.147': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.26.2 @@ -17260,18 +19071,18 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.19.5 - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/connect@3.4.38': @@ -17308,7 +19119,7 @@ snapshots: '@types/express-serve-static-core@4.19.5': dependencies: - '@types/node': 22.13.0 + '@types/node': 22.13.1 '@types/qs': 6.9.16 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -17339,7 +19150,7 @@ snapshots: '@types/http-proxy@1.17.15': dependencies: - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/istanbul-lib-coverage@2.0.5': {} @@ -17391,6 +19202,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@22.13.1': + dependencies: + undici-types: 6.20.0 + '@types/node@22.7.5': dependencies: undici-types: 6.19.8 @@ -17445,7 +19260,7 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/serve-index@1.9.4': @@ -17456,13 +19271,19 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.13.0 + '@types/node': 22.13.1 '@types/send': 0.17.4 optional: true + '@types/sinon@17.0.4': + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + + '@types/sinonjs__fake-timers@8.1.5': {} + '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.13.0 + '@types/node': 22.13.1 optional: true '@types/stack-utils@2.0.2': {} @@ -17830,14 +19651,23 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@2.1.8(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.0)(sass-embedded@1.83.0)(terser@5.31.0))': + '@vitest/mocker@2.1.8(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: msw: 2.7.0(@types/node@22.13.0)(typescript@5.7.2) - vite: 5.4.8(@types/node@22.13.0)(sass-embedded@1.83.0)(terser@5.31.0) + vite: 5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0) + + '@vitest/mocker@2.1.8(msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.7.0(@types/node@22.13.1)(typescript@5.7.2) + vite: 5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0) '@vitest/mocker@3.0.6(msw@2.7.0(@types/node@20.16.10)(typescript@5.7.2))(vite@6.1.1(@types/node@20.16.10)(jiti@1.21.6)(sass-embedded@1.83.0)(terser@5.31.0)(yaml@2.6.1))': dependencies: @@ -18251,6 +20081,32 @@ snapshots: transitivePeerDependencies: - supports-color + aws-lambda@1.0.7: + dependencies: + aws-sdk: 2.1692.0 + commander: 3.0.2 + js-yaml: 3.14.1 + watchpack: 2.4.1 + + aws-sdk-client-mock@4.1.0: + dependencies: + '@types/sinon': 17.0.4 + sinon: 18.0.1 + tslib: 2.8.1 + + aws-sdk@2.1692.0: + dependencies: + buffer: 4.9.2 + events: 1.1.1 + ieee754: 1.1.13 + jmespath: 0.16.0 + querystring: 0.2.0 + sax: 1.2.1 + url: 0.10.3 + util: 0.12.5 + uuid: 8.0.0 + xml2js: 0.6.2 + axios@1.7.7: dependencies: follow-redirects: 1.15.9 @@ -18574,6 +20430,12 @@ snapshots: buffer-from@1.1.2: {} + buffer@4.9.2: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 + buffer@5.6.0: dependencies: base64-js: 1.5.1 @@ -18605,6 +20467,11 @@ snapshots: cac@6.7.14: {} + call-bind-apply-helpers@1.0.1: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -18613,6 +20480,11 @@ snapshots: get-intrinsic: 1.2.4 set-function-length: 1.2.2 + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.7 + caller-callsite@2.0.0: dependencies: callsites: 2.0.0 @@ -18853,6 +20725,8 @@ snapshots: commander@2.20.3: {} + commander@3.0.2: {} + commander@4.1.1: {} commander@9.5.0: {} @@ -19009,13 +20883,28 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)): + create-jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -19273,6 +21162,12 @@ snapshots: dotenv@16.4.5: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: @@ -19402,6 +21297,8 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + es-define-property@1.0.1: {} + es-errors@1.3.0: {} es-iterator-helpers@1.0.19: @@ -19445,6 +21342,8 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 + es-toolkit@1.32.0: {} + esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -19571,24 +21470,35 @@ snapshots: - supports-color - typescript - eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)))(typescript@5.7.2): + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)))(typescript@5.7.2): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.7.2) eslint: 8.57.0 optionalDependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2) - jest: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + jest: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)))(typescript@5.0.4): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.0.4) + eslint: 8.57.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4) + jest: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)))(typescript@5.0.4): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)))(typescript@5.0.4): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.0.4) eslint: 8.57.0 optionalDependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.0.4))(eslint@8.57.0)(typescript@5.0.4) - jest: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.0.4)) + jest: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) transitivePeerDependencies: - supports-color - typescript @@ -19749,6 +21659,8 @@ snapshots: eventemitter3@4.0.7: optional: true + events@1.1.1: {} + events@3.3.0: {} execa@1.0.0: @@ -20150,8 +22062,26 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-intrinsic@1.2.7: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + get-package-type@0.1.0: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.0.0 + get-source@2.0.12: dependencies: data-uri-to-buffer: 2.0.2 @@ -20266,6 +22196,8 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} graphemer@1.4.0: {} @@ -20294,6 +22226,8 @@ snapshots: has-symbols@1.0.3: {} + has-symbols@1.1.0: {} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 @@ -20571,6 +22505,8 @@ snapshots: safer-buffer: 2.1.2 optional: true + ieee754@1.1.13: {} + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -20658,6 +22594,11 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 @@ -21003,16 +22944,35 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)): + jest-cli@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-cli@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + create-jest: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -21084,7 +23044,38 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)): + jest-config@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)): + dependencies: + '@babel/core': 7.26.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.13.0 + ts-node: 10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -21110,7 +23101,69 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 22.13.0 - ts-node: 10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2) + ts-node: 10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)): + dependencies: + '@babel/core': 7.26.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.13.1 + ts-node: 10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)): + dependencies: + '@babel/core': 7.26.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.13.1 + ts-node: 10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -21387,12 +23440,24 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)): + jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest@29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@22.13.0)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2)) + jest-cli: 29.7.0(@types/node@22.13.1)(ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -21403,6 +23468,8 @@ snapshots: jju@1.4.0: {} + jmespath@0.16.0: {} + joi@17.11.0: dependencies: '@hapi/hoek': 9.3.0 @@ -21619,6 +23686,8 @@ snapshots: readable-stream: 2.3.8 setimmediate: 1.0.5 + just-extend@6.2.0: {} + jwa@1.4.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -21713,6 +23782,8 @@ snapshots: lodash.debounce@4.0.8: {} + lodash.get@4.4.2: {} + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -21802,6 +23873,8 @@ snapshots: marky@1.2.5: {} + math-intrinsics@1.1.0: {} + mdast-util-definitions@5.1.2: dependencies: '@types/mdast': 3.0.15 @@ -22994,6 +25067,32 @@ snapshots: - '@types/node' optional: true + msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.1.6(@types/node@22.13.1) + '@mswjs/interceptors': 0.37.6 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + graphql: 16.10.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + strict-event-emitter: 0.5.1 + type-fest: 4.35.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.7.2 + transitivePeerDependencies: + - '@types/node' + optional: true + multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 @@ -23024,6 +25123,14 @@ snapshots: nice-try@1.0.5: {} + nise@6.1.1: + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/text-encoding': 0.7.3 + just-extend: 6.2.0 + path-to-regexp: 8.2.0 + nocache@3.0.4: {} node-abort-controller@3.1.1: {} @@ -23425,6 +25532,8 @@ snapshots: path-to-regexp@6.3.0: {} + path-to-regexp@8.2.0: {} + path-type@4.0.0: {} path-type@5.0.0: {} @@ -23728,6 +25837,8 @@ snapshots: end-of-stream: 1.4.4 once: 1.4.0 + punycode@1.3.2: {} + punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -23737,6 +25848,8 @@ snapshots: side-channel: 1.0.6 optional: true + querystring@0.2.0: {} + querystring@0.2.1: {} querystringify@2.2.0: {} @@ -24643,6 +26756,8 @@ snapshots: sass-embedded-win32-ia32: 1.83.0 sass-embedded-win32-x64: 1.83.0 + sax@1.2.1: {} + saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -24840,6 +26955,15 @@ snapshots: signal-exit@4.1.0: {} + sinon@18.0.1: + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers': 11.2.2 + '@sinonjs/samsam': 8.0.2 + diff: 5.2.0 + nise: 6.1.1 + supports-color: 7.2.0 + sisteransi@1.0.5: {} slash@3.0.0: {} @@ -25328,14 +27452,14 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.1(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2): + ts-node@10.9.1(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.13.0 + '@types/node': 22.13.1 acorn: 8.10.0 acorn-walk: 8.3.2 arg: 4.1.3 @@ -25390,14 +27514,35 @@ snapshots: '@swc/core': 1.7.42(@swc/helpers@0.5.15) optional: true - ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.0)(typescript@5.7.2): + ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.0.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.13.0 + '@types/node': 22.13.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.7.42(@swc/helpers@0.5.15) + optional: true + + ts-node@10.9.2(@swc/core@1.7.42(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.7.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.1 acorn: 8.14.0 acorn-walk: 8.3.2 arg: 4.1.3 @@ -25495,6 +27640,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.20.2: {} type-fest@0.21.3: {} @@ -25703,14 +27850,29 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + url@0.10.3: + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + use-sync-external-store@1.2.0(react@18.2.0): dependencies: react: 18.2.0 util-deprecate@1.0.2: {} + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + utils-merge@1.0.1: {} + uuid@8.0.0: {} + uuid@8.3.2: optional: true @@ -25795,6 +27957,24 @@ snapshots: - supports-color - terser + vite-node@2.1.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.6.0 + pathe: 1.1.2 + vite: 5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@3.0.6(@types/node@20.16.10)(jiti@1.21.6)(sass-embedded@1.83.0)(terser@5.31.0)(yaml@2.6.1): dependencies: cac: 6.7.14 @@ -25851,6 +28031,17 @@ snapshots: sass-embedded: 1.83.0 terser: 5.31.0 + vite@5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.32.1 + optionalDependencies: + '@types/node': 22.13.1 + fsevents: 2.3.3 + sass-embedded: 1.83.0 + terser: 5.31.0 + vite@6.1.1(@types/node@20.16.10)(jiti@1.21.6)(sass-embedded@1.83.0)(terser@5.31.0)(yaml@2.6.1): dependencies: esbuild: 0.24.2 @@ -25884,7 +28075,7 @@ snapshots: vitest@2.1.8(@types/node@22.13.0)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.0)(sass-embedded@1.83.0)(terser@5.31.0)) + '@vitest/mocker': 2.1.8(msw@2.7.0(@types/node@22.13.0)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 @@ -25917,6 +28108,42 @@ snapshots: - supports-color - terser + vitest@2.1.8(@types/node@22.13.1)(jsdom@25.0.1)(msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(msw@2.7.0(@types/node@22.13.1)(typescript@5.7.2))(vite@5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0) + vite-node: 2.1.8(@types/node@22.13.1)(sass-embedded@1.83.0)(terser@5.31.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.13.1 + jsdom: 25.0.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@3.0.6(@types/debug@4.1.12)(@types/node@20.16.10)(jiti@1.21.6)(jsdom@25.0.1)(msw@2.7.0(@types/node@20.16.10)(typescript@5.7.2))(sass-embedded@1.83.0)(terser@5.31.0)(yaml@2.6.1): dependencies: '@vitest/expect': 3.0.6 @@ -26287,6 +28514,13 @@ snapshots: xml-name-validator@5.0.0: optional: true + xml2js@0.6.2: + dependencies: + sax: 1.2.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + xmlbuilder@15.1.1: {} xmlchars@2.2.0: