From 525e249d41085592b4c9d56ee27cb12f6ae6fd65 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 12 Dec 2024 18:14:53 +0000 Subject: [PATCH 01/57] First pass at migrating to AWS SDK v3. --- packages/backend-core/package.json | 5 +- .../src/objectStore/buckets/app.ts | 8 +- .../src/objectStore/buckets/global.ts | 8 +- .../src/objectStore/buckets/plugins.ts | 22 +- .../src/objectStore/buckets/tests/app.spec.ts | 8 +- .../objectStore/buckets/tests/global.spec.ts | 8 +- .../src/objectStore/objectStore.ts | 177 ++- .../backend-core/src/objectStore/utils.ts | 9 +- packages/cli/src/backups/objectStore.ts | 25 +- packages/server/package.json | 5 +- .../server/src/api/controllers/application.ts | 2 +- .../src/api/controllers/static/index.ts | 26 +- .../src/automations/tests/createRow.spec.ts | 18 +- packages/server/src/integrations/dynamodb.ts | 38 +- packages/server/src/integrations/s3.ts | 57 +- .../server/src/integrations/utils/utils.ts | 2 +- .../src/utilities/rowProcessor/index.ts | 14 +- .../src/api/controllers/global/configs.ts | 46 +- yarn.lock | 1143 ++++++++++++++++- 19 files changed, 1352 insertions(+), 269 deletions(-) diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 3e1b5f324b..4339ee0a94 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -30,6 +30,9 @@ "test:watch": "jest --watchAll" }, "dependencies": { + "@aws-sdk/client-s3": "3.709.0", + "@aws-sdk/lib-storage": "3.709.0", + "@aws-sdk/s3-request-presigner": "3.709.0", "@budibase/nano": "10.1.5", "@budibase/pouchdb-replication-stream": "1.2.11", "@budibase/shared-core": "*", @@ -76,6 +79,7 @@ "@types/chance": "1.1.3", "@types/cookies": "0.7.8", "@types/jest": "29.5.5", + "@types/koa": "2.13.4", "@types/lodash": "4.14.200", "@types/node-fetch": "2.6.4", "@types/pouchdb": "6.4.2", @@ -83,7 +87,6 @@ "@types/semver": "7.3.7", "@types/tar-fs": "2.0.1", "@types/uuid": "8.3.4", - "@types/koa": "2.13.4", "chance": "1.1.8", "ioredis-mock": "8.9.0", "jest": "29.7.0", diff --git a/packages/backend-core/src/objectStore/buckets/app.ts b/packages/backend-core/src/objectStore/buckets/app.ts index 43bc965c65..dbf49ca994 100644 --- a/packages/backend-core/src/objectStore/buckets/app.ts +++ b/packages/backend-core/src/objectStore/buckets/app.ts @@ -13,7 +13,7 @@ export function clientLibraryPath(appId: string) { * due to issues with the domain we were unable to continue doing this - keeping * incase we are able to switch back to CDN path again in future. */ -export function clientLibraryCDNUrl(appId: string, version: string) { +export async function clientLibraryCDNUrl(appId: string, version: string) { let file = clientLibraryPath(appId) if (env.CLOUDFRONT_CDN) { // append app version to bust the cache @@ -24,7 +24,7 @@ export function clientLibraryCDNUrl(appId: string, version: string) { // file is public return cloudfront.getUrl(file) } else { - return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) + return await objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) } } @@ -44,10 +44,10 @@ export function clientLibraryUrl(appId: string, version: string) { return `/api/assets/client?${qs.encode(qsParams)}` } -export function getAppFileUrl(s3Key: string) { +export async function getAppFileUrl(s3Key: string) { if (env.CLOUDFRONT_CDN) { return cloudfront.getPresignedUrl(s3Key) } else { - return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key) + return await objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key) } } diff --git a/packages/backend-core/src/objectStore/buckets/global.ts b/packages/backend-core/src/objectStore/buckets/global.ts index 69e201bb98..29c3347b05 100644 --- a/packages/backend-core/src/objectStore/buckets/global.ts +++ b/packages/backend-core/src/objectStore/buckets/global.ts @@ -5,7 +5,11 @@ import * as cloudfront from "../cloudfront" // URLs -export const getGlobalFileUrl = (type: string, name: string, etag?: string) => { +export const getGlobalFileUrl = async ( + type: string, + name: string, + etag?: string +) => { let file = getGlobalFileS3Key(type, name) if (env.CLOUDFRONT_CDN) { if (etag) { @@ -13,7 +17,7 @@ export const getGlobalFileUrl = (type: string, name: string, etag?: string) => { } return cloudfront.getPresignedUrl(file) } else { - return objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file) + return await objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file) } } diff --git a/packages/backend-core/src/objectStore/buckets/plugins.ts b/packages/backend-core/src/objectStore/buckets/plugins.ts index 02be9345ab..131f180f48 100644 --- a/packages/backend-core/src/objectStore/buckets/plugins.ts +++ b/packages/backend-core/src/objectStore/buckets/plugins.ts @@ -6,23 +6,25 @@ import { Plugin } from "@budibase/types" // URLS -export function enrichPluginURLs(plugins?: Plugin[]): Plugin[] { +export async function enrichPluginURLs(plugins?: Plugin[]): Promise { if (!plugins || !plugins.length) { return [] } - return plugins.map(plugin => { - const jsUrl = getPluginJSUrl(plugin) - const iconUrl = getPluginIconUrl(plugin) - return { ...plugin, jsUrl, iconUrl } - }) + return await Promise.all( + plugins.map(async plugin => { + const jsUrl = await getPluginJSUrl(plugin) + const iconUrl = await getPluginIconUrl(plugin) + return { ...plugin, jsUrl, iconUrl } + }) + ) } -function getPluginJSUrl(plugin: Plugin) { +async function getPluginJSUrl(plugin: Plugin) { const s3Key = getPluginJSKey(plugin) return getPluginUrl(s3Key) } -function getPluginIconUrl(plugin: Plugin): string | undefined { +async function getPluginIconUrl(plugin: Plugin) { const s3Key = getPluginIconKey(plugin) if (!s3Key) { return @@ -30,11 +32,11 @@ function getPluginIconUrl(plugin: Plugin): string | undefined { return getPluginUrl(s3Key) } -function getPluginUrl(s3Key: string) { +async function getPluginUrl(s3Key: string) { if (env.CLOUDFRONT_CDN) { return cloudfront.getPresignedUrl(s3Key) } else { - return objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key) + return await objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key) } } diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index 4a132ce54d..1aeba8f2c2 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -109,9 +109,9 @@ describe("app", () => { ) }) - it("gets url with cloudfront + s3", () => { + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - const url = getAppFileUrl() + const url = await getAppFileUrl() // omit rest of signed params expect( url.includes("http://cf.example.com/app_123/attachments/image.jpeg?") @@ -146,8 +146,8 @@ describe("app", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(() => { - const url = getAppFileUrl() + await testEnv.withTenant(async () => { + const url = await getAppFileUrl() // omit rest of signed params expect( url.includes( diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index 148a4c80bf..be459a7a23 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -24,9 +24,9 @@ describe("global", () => { expect(url).toBe("http://s3.example.com/global/settings/logoUrl") }) - it("gets url with cloudfront + s3", () => { + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - const url = getGlobalFileUrl() + const url = await getGlobalFileUrl() // omit rest of signed params expect( url.includes("http://cf.example.com/settings/logoUrl?etag=etag&") @@ -59,8 +59,8 @@ describe("global", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(tenantId => { - const url = getGlobalFileUrl() + await testEnv.withTenant(async tenantId => { + const url = await getGlobalFileUrl() // omit rest of signed params expect( url.includes( diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 79875b5e99..6acf2e21ae 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -1,6 +1,15 @@ const sanitize = require("sanitize-s3-objectkey") -import AWS from "aws-sdk" +import { + HeadObjectCommandOutput, + PutObjectCommandInput, + S3, + S3ClientConfig, + GetObjectCommand, + _Object as S3Object, +} from "@aws-sdk/client-s3" +import { Upload } from "@aws-sdk/lib-storage" +import { getSignedUrl } from "@aws-sdk/s3-request-presigner" import stream, { Readable } from "stream" import fetch from "node-fetch" import tar from "tar-fs" @@ -13,7 +22,6 @@ import { bucketTTLConfig, budibaseTempDir } from "./utils" import { v4 } from "uuid" import { APP_PREFIX, APP_DEV_PREFIX } from "../db" import fsp from "fs/promises" -import { HeadObjectOutput } from "aws-sdk/clients/s3" import { ReadableStream } from "stream/web" const streamPipeline = promisify(stream.pipeline) @@ -84,26 +92,24 @@ export function sanitizeBucket(input: string) { * @constructor */ export function ObjectStore( - bucket: string, opts: { presigning: boolean } = { presigning: false } ) { - const config: AWS.S3.ClientConfiguration = { - s3ForcePathStyle: true, - signatureVersion: "v4", - apiVersion: "2006-03-01", - accessKeyId: env.MINIO_ACCESS_KEY, - secretAccessKey: env.MINIO_SECRET_KEY, + const config: S3ClientConfig = { + forcePathStyle: true, + credentials: { + accessKeyId: env.MINIO_ACCESS_KEY!, + secretAccessKey: env.MINIO_SECRET_KEY!, + }, region: env.AWS_REGION, } - if (bucket) { - config.params = { - Bucket: sanitizeBucket(bucket), - } - } // for AWS Credentials using temporary session token if (!env.MINIO_ENABLED && env.AWS_SESSION_TOKEN) { - config.sessionToken = env.AWS_SESSION_TOKEN + config.credentials = { + accessKeyId: env.MINIO_ACCESS_KEY!, + secretAccessKey: env.MINIO_SECRET_KEY!, + sessionToken: env.AWS_SESSION_TOKEN, + } } // custom S3 is in use i.e. minio @@ -119,7 +125,7 @@ export function ObjectStore( } } - return new AWS.S3(config) + return new S3(config) } /** @@ -132,7 +138,9 @@ export async function createBucketIfNotExists( ): Promise<{ created: boolean; exists: boolean }> { bucketName = sanitizeBucket(bucketName) try { - await client + await // The `.promise()` call might be on an JS SDK v2 client API. + // If yes, please remove .promise(). If not, remove this comment. + client .headBucket({ Bucket: bucketName, }) @@ -147,11 +155,13 @@ export async function createBucketIfNotExists( return { created: false, exists: true } } else if (doesntExist || noAccess) { if (doesntExist) { - promises[bucketName] = client - .createBucket({ - Bucket: bucketName, - }) - .promise() + promises[bucketName] = // The `.promise()` call might be on an JS SDK v2 client API. + // If yes, please remove .promise(). If not, remove this comment. + client + .createBucket({ + Bucket: bucketName, + }) + .promise() await promises[bucketName] delete promises[bucketName] return { created: true, exists: false } @@ -180,12 +190,12 @@ export async function upload({ const fileBytes = path ? (await fsp.open(path)).createReadStream() : body - const objectStore = ObjectStore(bucketName) + const objectStore = ObjectStore() const bucketCreated = await createBucketIfNotExists(objectStore, bucketName) if (ttl && bucketCreated.created) { let ttlConfig = bucketTTLConfig(bucketName, ttl) - await objectStore.putBucketLifecycleConfiguration(ttlConfig).promise() + await objectStore.putBucketLifecycleConfiguration(ttlConfig) } let contentType = type @@ -194,11 +204,12 @@ export async function upload({ ? CONTENT_TYPE_MAP[extension.toLowerCase()] : CONTENT_TYPE_MAP.txt } - const config: any = { + const config: PutObjectCommandInput = { // windows file paths need to be converted to forward slashes for s3 + Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filename), - Body: fileBytes, - ContentType: contentType, + Body: fileBytes as stream.Readable | Buffer, + ContentType: contentType!, } if (metadata && typeof metadata === "object") { // remove any nullish keys from the metadata object, as these may be considered invalid @@ -207,10 +218,15 @@ export async function upload({ delete metadata[key] } } - config.Metadata = metadata + config.Metadata = metadata as Record } - return objectStore.upload(config).promise() + const upload = new Upload({ + client: objectStore, + params: config, + }) + + return upload.done() } /** @@ -229,12 +245,12 @@ export async function streamUpload({ throw new Error("Stream to upload is invalid/undefined") } const extension = filename.split(".").pop() - const objectStore = ObjectStore(bucketName) + const objectStore = ObjectStore() const bucketCreated = await createBucketIfNotExists(objectStore, bucketName) if (ttl && bucketCreated.created) { let ttlConfig = bucketTTLConfig(bucketName, ttl) - await objectStore.putBucketLifecycleConfiguration(ttlConfig).promise() + await objectStore.putBucketLifecycleConfiguration(ttlConfig) } // Set content type for certain known extensions @@ -267,13 +283,15 @@ export async function streamUpload({ ...extra, } - const details = await objectStore.upload(params).promise() - const headDetails = await objectStore - .headObject({ - Bucket: bucket, - Key: objKey, - }) - .promise() + const upload = new Upload({ + client: objectStore, + params, + }) + const details = await upload.done() + const headDetails = await objectStore.headObject({ + Bucket: bucket, + Key: objKey, + }) return { ...details, ContentLength: headDetails.ContentLength, @@ -284,35 +302,42 @@ export async function streamUpload({ * retrieves the contents of a file from the object store, if it is a known content type it * will be converted, otherwise it will be returned as a buffer stream. */ -export async function retrieve(bucketName: string, filepath: string) { - const objectStore = ObjectStore(bucketName) +export async function retrieve( + bucketName: string, + filepath: string +): Promise { + const objectStore = ObjectStore() const params = { Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filepath), } - const response: any = await objectStore.getObject(params).promise() + const response = await objectStore.getObject(params) + if (!response.Body) { + throw new Error("Unable to retrieve object") + } // currently these are all strings if (STRING_CONTENT_TYPES.includes(response.ContentType)) { - return response.Body.toString("utf8") + return response.Body.toString() } else { - return response.Body + return response.Body as stream.Readable } } -export async function listAllObjects(bucketName: string, path: string) { - const objectStore = ObjectStore(bucketName) +export async function listAllObjects( + bucketName: string, + path: string +): Promise { + const objectStore = ObjectStore() const list = (params: ListParams = {}) => { - return objectStore - .listObjectsV2({ - ...params, - Bucket: sanitizeBucket(bucketName), - Prefix: sanitizeKey(path), - }) - .promise() + return objectStore.listObjectsV2({ + ...params, + Bucket: sanitizeBucket(bucketName), + Prefix: sanitizeKey(path), + }) } let isTruncated = false, token, - objects: AWS.S3.Types.Object[] = [] + objects: Object[] = [] do { let params: ListParams = {} if (token) { @@ -331,18 +356,19 @@ export async function listAllObjects(bucketName: string, path: string) { /** * Generate a presigned url with a default TTL of 1 hour */ -export function getPresignedUrl( +export async function getPresignedUrl( bucketName: string, key: string, durationSeconds = 3600 ) { - const objectStore = ObjectStore(bucketName, { presigning: true }) + const objectStore = ObjectStore({ presigning: true }) const params = { Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(key), - Expires: durationSeconds, } - const url = objectStore.getSignedUrl("getObject", params) + const url = await getSignedUrl(objectStore, new GetObjectCommand(params), { + expiresIn: durationSeconds, + }) if (!env.MINIO_ENABLED) { // return the full URL to the client @@ -366,7 +392,11 @@ export async function retrieveToTmp(bucketName: string, filepath: string) { filepath = sanitizeKey(filepath) const data = await retrieve(bucketName, filepath) const outputPath = join(budibaseTempDir(), v4()) - fs.writeFileSync(outputPath, data) + if (data instanceof stream.Readable) { + data.pipe(fs.createWriteStream(outputPath)) + } else { + fs.writeFileSync(outputPath, data) + } return outputPath } @@ -408,17 +438,17 @@ export async function retrieveDirectory(bucketName: string, path: string) { * Delete a single file. */ export async function deleteFile(bucketName: string, filepath: string) { - const objectStore = ObjectStore(bucketName) + const objectStore = ObjectStore() await createBucketIfNotExists(objectStore, bucketName) const params = { Bucket: bucketName, Key: sanitizeKey(filepath), } - return objectStore.deleteObject(params).promise() + return objectStore.deleteObject(params) } export async function deleteFiles(bucketName: string, filepaths: string[]) { - const objectStore = ObjectStore(bucketName) + const objectStore = ObjectStore() await createBucketIfNotExists(objectStore, bucketName) const params = { Bucket: bucketName, @@ -426,7 +456,7 @@ export async function deleteFiles(bucketName: string, filepaths: string[]) { Objects: filepaths.map((path: any) => ({ Key: sanitizeKey(path) })), }, } - return objectStore.deleteObjects(params).promise() + return objectStore.deleteObjects(params) } /** @@ -438,13 +468,16 @@ export async function deleteFolder( ): Promise { bucketName = sanitizeBucket(bucketName) folder = sanitizeKey(folder) - const client = ObjectStore(bucketName) + const client = ObjectStore() const listParams = { Bucket: bucketName, Prefix: folder, } - const existingObjectsResponse = await client.listObjects(listParams).promise() + const existingObjectsResponse = + await // The `.promise()` call might be on an JS SDK v2 client API. + // If yes, please remove .promise(). If not, remove this comment. + client.listObjects(listParams) if (existingObjectsResponse.Contents?.length === 0) { return } @@ -459,7 +492,7 @@ export async function deleteFolder( deleteParams.Delete.Objects.push({ Key: content.Key }) }) - const deleteResponse = await client.deleteObjects(deleteParams).promise() + const deleteResponse = await client.deleteObjects(deleteParams) // can only empty 1000 items at once if (deleteResponse.Deleted?.length === 1000) { return deleteFolder(bucketName, folder) @@ -534,29 +567,33 @@ export async function getReadStream( ): Promise { bucketName = sanitizeBucket(bucketName) path = sanitizeKey(path) - const client = ObjectStore(bucketName) + const client = ObjectStore() const params = { Bucket: bucketName, Key: path, } - return client.getObject(params).createReadStream() + const response = await client.getObject(params) + if (!response.Body || !(response.Body instanceof stream.Readable)) { + throw new Error("Unable to retrieve stream - invalid response") + } + return response.Body } export async function getObjectMetadata( bucket: string, path: string -): Promise { +): Promise { bucket = sanitizeBucket(bucket) path = sanitizeKey(path) - const client = ObjectStore(bucket) + const client = ObjectStore() const params = { Bucket: bucket, Key: path, } try { - return await client.headObject(params).promise() + return await client.headObject(params) } catch (err: any) { throw new Error("Unable to retrieve metadata from object") } diff --git a/packages/backend-core/src/objectStore/utils.ts b/packages/backend-core/src/objectStore/utils.ts index 30c2fefbf1..2a9dd26e02 100644 --- a/packages/backend-core/src/objectStore/utils.ts +++ b/packages/backend-core/src/objectStore/utils.ts @@ -2,7 +2,10 @@ import path, { join } from "path" import { tmpdir } from "os" import fs from "fs" import env from "../environment" -import { PutBucketLifecycleConfigurationRequest } from "aws-sdk/clients/s3" +import { + LifecycleRule, + PutBucketLifecycleConfigurationCommandInput, +} from "@aws-sdk/client-s3" import * as objectStore from "./objectStore" import { AutomationAttachment, @@ -43,8 +46,8 @@ export function budibaseTempDir() { export const bucketTTLConfig = ( bucketName: string, days: number -): PutBucketLifecycleConfigurationRequest => { - const lifecycleRule = { +): PutBucketLifecycleConfigurationCommandInput => { + const lifecycleRule: LifecycleRule = { ID: `${bucketName}-ExpireAfter${days}days`, Prefix: "", Status: "Enabled", diff --git a/packages/cli/src/backups/objectStore.ts b/packages/cli/src/backups/objectStore.ts index 2a24199603..34e231b87b 100644 --- a/packages/cli/src/backups/objectStore.ts +++ b/packages/cli/src/backups/objectStore.ts @@ -3,6 +3,7 @@ import fs from "fs" import { join } from "path" import { TEMP_DIR, MINIO_DIR } from "./utils" import { progressBar } from "../utils" +import * as stream from "node:stream" const { ObjectStoreBuckets, @@ -20,15 +21,21 @@ export async function exportObjects() { let fullList: any[] = [] let errorCount = 0 for (let bucket of bucketList) { - const client = ObjectStore(bucket) + const client = ObjectStore() try { - await client.headBucket().promise() + await client.headBucket({ + Bucket: bucket, + }) } catch (err) { errorCount++ continue } - const list = (await client.listObjectsV2().promise()) as { Contents: any[] } - fullList = fullList.concat(list.Contents.map(el => ({ ...el, bucket }))) + const list = await client.listObjectsV2({ + Bucket: bucket, + }) + fullList = fullList.concat( + list.Contents?.map(el => ({ ...el, bucket })) || [] + ) } if (errorCount === bucketList.length) { throw new Error("Unable to access MinIO/S3 - check environment config.") @@ -43,7 +50,13 @@ export async function exportObjects() { const dirs = possiblePath.slice(0, possiblePath.length - 1) fs.mkdirSync(join(path, object.bucket, ...dirs), { recursive: true }) } - fs.writeFileSync(join(path, object.bucket, ...possiblePath), data) + if (data instanceof stream.Readable) { + data.pipe( + fs.createWriteStream(join(path, object.bucket, ...possiblePath)) + ) + } else { + fs.writeFileSync(join(path, object.bucket, ...possiblePath), data) + } bar.update(++count) } bar.stop() @@ -60,7 +73,7 @@ export async function importObjects() { const bar = progressBar(total) let count = 0 for (let bucket of buckets) { - const client = ObjectStore(bucket) + const client = ObjectStore() await createBucketIfNotExists(client, bucket) const files = await uploadDirectory(bucket, join(path, bucket), "/") count += files.length diff --git a/packages/server/package.json b/packages/server/package.json index 1dd3df1d73..7431d0ad54 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -50,6 +50,10 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", + "@aws-sdk/client-dynamodb": "3.709.0", + "@aws-sdk/client-s3": "3.709.0", + "@aws-sdk/lib-dynamodb": "3.709.0", + "@aws-sdk/s3-request-presigner": "3.709.0", "@azure/msal-node": "^2.5.1", "@budibase/backend-core": "*", "@budibase/client": "*", @@ -70,7 +74,6 @@ "airtable": "0.12.2", "arangojs": "7.2.0", "archiver": "7.0.1", - "aws-sdk": "2.1692.0", "bcrypt": "5.1.0", "bcryptjs": "2.4.3", "bson": "^6.9.0", diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index d032f14150..d05f6f2eaa 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -225,7 +225,7 @@ export async function fetchAppPackage( const license = await licensing.cache.getCachedLicense() // Enrich plugin URLs - application.usedPlugins = objectStore.enrichPluginURLs( + application.usedPlugins = await objectStore.enrichPluginURLs( application.usedPlugins ) diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts index 0dd5e77c50..8b5c61e875 100644 --- a/packages/server/src/api/controllers/static/index.ts +++ b/packages/server/src/api/controllers/static/index.ts @@ -18,7 +18,8 @@ import { objectStore, utils, } from "@budibase/backend-core" -import AWS from "aws-sdk" +import { getSignedUrl } from "@aws-sdk/s3-request-presigner" +import { PutObjectCommand, S3 } from "@aws-sdk/client-s3" import fs from "fs" import sdk from "../../../sdk" import * as pro from "@budibase/pro" @@ -128,9 +129,9 @@ export const uploadFile = async function ( return { size: file.size, name: file.name, - url: objectStore.getAppFileUrl(s3Key), + url: await objectStore.getAppFileUrl(s3Key), extension, - key: response.Key, + key: response.Key!, } }) ) @@ -210,11 +211,11 @@ export const serveApp = async function (ctx: UserCtx) { usedPlugins: plugins, favicon: branding.faviconUrl !== "" - ? objectStore.getGlobalFileUrl("settings", "faviconUrl") + ? await objectStore.getGlobalFileUrl("settings", "faviconUrl") : "", logo: config?.logoUrl !== "" - ? objectStore.getGlobalFileUrl("settings", "logoUrl") + ? await objectStore.getGlobalFileUrl("settings", "logoUrl") : "", appMigrating: needMigrations, nonce: ctx.state.nonce, @@ -243,7 +244,7 @@ export const serveApp = async function (ctx: UserCtx) { metaDescription: branding?.metaDescription || "", favicon: branding.faviconUrl !== "" - ? objectStore.getGlobalFileUrl("settings", "faviconUrl") + ? await objectStore.getGlobalFileUrl("settings", "faviconUrl") : "", }) @@ -334,16 +335,17 @@ export const getSignedUploadURL = async function ( ctx.throw(400, "bucket and key values are required") } try { - const s3 = new AWS.S3({ + const s3 = new S3({ region: awsRegion, endpoint: datasource?.config?.endpoint || undefined, - accessKeyId: datasource?.config?.accessKeyId as string, - secretAccessKey: datasource?.config?.secretAccessKey as string, - apiVersion: "2006-03-01", - signatureVersion: "v4", + + credentials: { + accessKeyId: datasource?.config?.accessKeyId as string, + secretAccessKey: datasource?.config?.secretAccessKey as string, + }, }) const params = { Bucket: bucket, Key: key } - signedUrl = s3.getSignedUrl("putObject", params) + signedUrl = await getSignedUrl(s3, new PutObjectCommand(params)) if (datasource?.config?.endpoint) { publicUrl = `${datasource.config.endpoint}/${bucket}/${key}` } else { diff --git a/packages/server/src/automations/tests/createRow.spec.ts b/packages/server/src/automations/tests/createRow.spec.ts index bd78de2217..42b69324e2 100644 --- a/packages/server/src/automations/tests/createRow.spec.ts +++ b/packages/server/src/automations/tests/createRow.spec.ts @@ -154,11 +154,12 @@ describe("test the create row action", () => { expect(result.steps[1].outputs.row.file_attachment[0]).toHaveProperty("key") let s3Key = result.steps[1].outputs.row.file_attachment[0].key - const client = objectStore.ObjectStore(objectStore.ObjectStoreBuckets.APPS) + const client = objectStore.ObjectStore() - const objectData = await client - .headObject({ Bucket: objectStore.ObjectStoreBuckets.APPS, Key: s3Key }) - .promise() + const objectData = await client.headObject({ + Bucket: objectStore.ObjectStoreBuckets.APPS, + Key: s3Key, + }) expect(objectData).toBeDefined() expect(objectData.ContentLength).toBeGreaterThan(0) @@ -229,11 +230,12 @@ describe("test the create row action", () => { ) let s3Key = result.steps[1].outputs.row.single_file_attachment.key - const client = objectStore.ObjectStore(objectStore.ObjectStoreBuckets.APPS) + const client = objectStore.ObjectStore() - const objectData = await client - .headObject({ Bucket: objectStore.ObjectStoreBuckets.APPS, Key: s3Key }) - .promise() + const objectData = await client.headObject({ + Bucket: objectStore.ObjectStoreBuckets.APPS, + Key: s3Key, + }) expect(objectData).toBeDefined() expect(objectData.ContentLength).toBeGreaterThan(0) diff --git a/packages/server/src/integrations/dynamodb.ts b/packages/server/src/integrations/dynamodb.ts index 424a3dfce0..96941ebb0e 100644 --- a/packages/server/src/integrations/dynamodb.ts +++ b/packages/server/src/integrations/dynamodb.ts @@ -7,9 +7,15 @@ import { ConnectionInfo, } from "@budibase/types" -import AWS from "aws-sdk" +import { + DynamoDBDocument, + PutCommandInput, + GetCommandInput, + UpdateCommandInput, + DeleteCommandInput, +} from "@aws-sdk/lib-dynamodb" +import { DynamoDB } from "@aws-sdk/client-dynamodb" import { AWS_REGION } from "../constants" -import { DocumentClient } from "aws-sdk/clients/dynamodb" interface DynamoDBConfig { region: string @@ -151,7 +157,7 @@ class DynamoDBIntegration implements IntegrationBase { region: config.region || AWS_REGION, endpoint: config.endpoint || undefined, } - this.client = new AWS.DynamoDB.DocumentClient(this.config) + this.client = DynamoDBDocument.from(new DynamoDB(this.config)) } async testConnection() { @@ -159,8 +165,8 @@ class DynamoDBIntegration implements IntegrationBase { connected: false, } try { - const scanRes = await new AWS.DynamoDB(this.config).listTables().promise() - response.connected = !!scanRes.$response + const scanRes = await new DynamoDB(this.config).listTables() + response.connected = !!scanRes.$metadata } catch (e: any) { response.error = e.message as string } @@ -169,13 +175,13 @@ class DynamoDBIntegration implements IntegrationBase { async create(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.put(params).promise() + return this.client.put(params) } async read(query: { table: string; json: object; index: null | string }) { @@ -184,7 +190,7 @@ class DynamoDBIntegration implements IntegrationBase { IndexName: query.index ? query.index : undefined, ...query.json, } - const response = await this.client.query(params).promise() + const response = await this.client.query(params) if (response.Items) { return response.Items } @@ -197,7 +203,7 @@ class DynamoDBIntegration implements IntegrationBase { IndexName: query.index ? query.index : undefined, ...query.json, } - const response = await this.client.scan(params).promise() + const response = await this.client.scan(params) if (response.Items) { return response.Items } @@ -208,40 +214,40 @@ class DynamoDBIntegration implements IntegrationBase { const params = { TableName: query.table, } - return new AWS.DynamoDB(this.config).describeTable(params).promise() + return new DynamoDB(this.config).describeTable(params) } async get(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.get(params).promise() + return this.client.get(params) } async update(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.update(params).promise() + return this.client.update(params) } async delete(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.delete(params).promise() + return this.client.delete(params) } } diff --git a/packages/server/src/integrations/s3.ts b/packages/server/src/integrations/s3.ts index 0b7d774048..488c22835a 100644 --- a/packages/server/src/integrations/s3.ts +++ b/packages/server/src/integrations/s3.ts @@ -7,8 +7,9 @@ import { ConnectionInfo, } from "@budibase/types" -import AWS from "aws-sdk" +import { S3 } from "@aws-sdk/client-s3" import csv from "csvtojson" +import stream from "stream" interface S3Config { region: string @@ -167,7 +168,7 @@ class S3Integration implements IntegrationBase { delete this.config.endpoint } - this.client = new AWS.S3(this.config) + this.client = new S3(this.config) } async testConnection() { @@ -175,7 +176,7 @@ class S3Integration implements IntegrationBase { connected: false, } try { - await this.client.listBuckets().promise() + await this.client.listBuckets() response.connected = true } catch (e: any) { response.error = e.message as string @@ -209,7 +210,7 @@ class S3Integration implements IntegrationBase { LocationConstraint: query.location, } } - return await this.client.createBucket(params).promise() + return await this.client.createBucket(params) } async read(query: { @@ -220,37 +221,39 @@ class S3Integration implements IntegrationBase { maxKeys: number prefix: string }) { - const response = await this.client - .listObjects({ - Bucket: query.bucket, - Delimiter: query.delimiter, - Marker: query.marker, - MaxKeys: query.maxKeys, - Prefix: query.prefix, - }) - .promise() + const response = await this.client.listObjects({ + Bucket: query.bucket, + Delimiter: query.delimiter, + Marker: query.marker, + MaxKeys: query.maxKeys, + Prefix: query.prefix, + }) return response.Contents } async readCsv(query: { bucket: string; key: string }) { - const stream = this.client - .getObject({ - Bucket: query.bucket, - Key: query.key, - }) - .createReadStream() + const response = await this.client.getObject({ + Bucket: query.bucket, + Key: query.key, + }) + + const fileStream = response.Body?.transformToWebStream() + + if (!fileStream || !(fileStream instanceof stream.Readable)) { + throw new Error("Unable to retrieve CSV - invalid stream") + } let csvError = false return new Promise((resolve, reject) => { - stream.on("error", (err: Error) => { + fileStream.on("error", (err: Error) => { reject(err) }) const response = csv() - .fromStream(stream) + .fromStream(fileStream) .on("error", () => { csvError = true }) - stream.on("finish", () => { + fileStream.on("finish", () => { resolve(response) }) }).catch(err => { @@ -263,12 +266,10 @@ class S3Integration implements IntegrationBase { } async delete(query: { bucket: string; delete: string }) { - return await this.client - .deleteObjects({ - Bucket: query.bucket, - Delete: JSON.parse(query.delete), - }) - .promise() + return await this.client.deleteObjects({ + Bucket: query.bucket, + Delete: JSON.parse(query.delete), + }) } } diff --git a/packages/server/src/integrations/utils/utils.ts b/packages/server/src/integrations/utils/utils.ts index 315a8010e8..db9148ae90 100644 --- a/packages/server/src/integrations/utils/utils.ts +++ b/packages/server/src/integrations/utils/utils.ts @@ -430,7 +430,7 @@ export async function handleFileResponse( size = details.ContentLength } } - presignedUrl = objectStore.getPresignedUrl(bucket, key) + presignedUrl = await objectStore.getPresignedUrl(bucket, key) return { data: { size, diff --git a/packages/server/src/utilities/rowProcessor/index.ts b/packages/server/src/utilities/rowProcessor/index.ts index 14b524fd95..7c01c54f13 100644 --- a/packages/server/src/utilities/rowProcessor/index.ts +++ b/packages/server/src/utilities/rowProcessor/index.ts @@ -359,9 +359,9 @@ export async function coreOutputProcessing( if (row[property] == null) { continue } - const process = (attachment: RowAttachment) => { + const process = async (attachment: RowAttachment) => { if (!attachment.url && attachment.key) { - attachment.url = objectStore.getAppFileUrl(attachment.key) + attachment.url = await objectStore.getAppFileUrl(attachment.key) } return attachment } @@ -369,11 +369,13 @@ export async function coreOutputProcessing( row[property] = JSON.parse(row[property]) } if (Array.isArray(row[property])) { - row[property].forEach((attachment: RowAttachment) => { - process(attachment) - }) + await Promise.all( + row[property].map((attachment: RowAttachment) => + process(attachment) + ) + ) } else { - process(row[property]) + await process(row[property]) } } } else if ( diff --git a/packages/worker/src/api/controllers/global/configs.ts b/packages/worker/src/api/controllers/global/configs.ts index a10fce35f6..4ee8dcbb24 100644 --- a/packages/worker/src/api/controllers/global/configs.ts +++ b/packages/worker/src/api/controllers/global/configs.ts @@ -322,27 +322,27 @@ export async function save( } } -function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) { +async function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) { if (!oidcLogos) { return } - oidcLogos.config = Object.keys(oidcLogos.config || {}).reduce( - (acc: any, key: string) => { - if (!key.endsWith("Etag")) { - const etag = oidcLogos.config[`${key}Etag`] - const objectStoreUrl = objectStore.getGlobalFileUrl( - oidcLogos.type, - key, - etag - ) - acc[key] = objectStoreUrl - } else { - acc[key] = oidcLogos.config[key] - } - return acc - }, - {} - ) + const newConfig: Record = {} + const keys = Object.keys(oidcLogos.config || {}) + + for (const key of keys) { + if (!key.endsWith("Etag")) { + const etag = oidcLogos.config[`${key}Etag`] + const objectStoreUrl = await objectStore.getGlobalFileUrl( + oidcLogos.type, + key, + etag + ) + newConfig[key] = objectStoreUrl + } else { + newConfig[key] = oidcLogos.config[key] + } + } + oidcLogos.config = newConfig } export async function find(ctx: UserCtx) { @@ -370,7 +370,7 @@ export async function find(ctx: UserCtx) { async function handleConfigType(type: ConfigType, config: Config) { if (type === ConfigType.OIDC_LOGOS) { - enrichOIDCLogos(config) + await enrichOIDCLogos(config) } else if (type === ConfigType.AI) { await handleAIConfig(config) } @@ -396,7 +396,7 @@ export async function publicOidc(ctx: Ctx) { const oidcCustomLogos = await configs.getOIDCLogosDoc() if (oidcCustomLogos) { - enrichOIDCLogos(oidcCustomLogos) + await enrichOIDCLogos(oidcCustomLogos) } if (!oidcConfig) { @@ -427,7 +427,7 @@ export async function publicSettings( // enrich the logo url - empty url means deleted if (config.logoUrl && config.logoUrl !== "") { - config.logoUrl = objectStore.getGlobalFileUrl( + config.logoUrl = await objectStore.getGlobalFileUrl( "settings", "logoUrl", config.logoUrlEtag @@ -437,7 +437,7 @@ export async function publicSettings( // enrich the favicon url - empty url means deleted const faviconUrl = branding.faviconUrl && branding.faviconUrl !== "" - ? objectStore.getGlobalFileUrl( + ? await objectStore.getGlobalFileUrl( "settings", "faviconUrl", branding.faviconUrlEtag @@ -522,7 +522,7 @@ export async function upload(ctx: UserCtx) { ctx.body = { message: "File has been uploaded and url stored to config.", - url: objectStore.getGlobalFileUrl(type, name, etag), + url: await objectStore.getGlobalFileUrl(type, name, etag), } } diff --git a/yarn.lock b/yarn.lock index aa409fe4a1..657a551f1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -150,6 +150,121 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" +"@aws-sdk/client-dynamodb@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-dynamodb/-/client-dynamodb-3.709.0.tgz#589cfab9d27f7d0d2056f72e4674315ccd98b6bc" + integrity sha512-p/GVuEgfPccFUm5lxr7EPi5gQAsUO4SDdKcIV+v/dNwtH2SXEgnFN0o1TEIJtuVY3BsQyXyR1aMjeQ81O832kw== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/client-sso-oidc" "3.709.0" + "@aws-sdk/client-sts" "3.709.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/credential-provider-node" "3.709.0" + "@aws-sdk/middleware-endpoint-discovery" "3.709.0" + "@aws-sdk/middleware-host-header" "3.709.0" + "@aws-sdk/middleware-logger" "3.709.0" + "@aws-sdk/middleware-recursion-detection" "3.709.0" + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/region-config-resolver" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@aws-sdk/util-user-agent-browser" "3.709.0" + "@aws-sdk/util-user-agent-node" "3.709.0" + "@smithy/config-resolver" "^3.0.13" + "@smithy/core" "^2.5.5" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/hash-node" "^3.0.11" + "@smithy/invalid-dependency" "^3.0.11" + "@smithy/middleware-content-length" "^3.0.13" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-retry" "^3.0.30" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-body-length-node" "^3.0.0" + "@smithy/util-defaults-mode-browser" "^3.0.30" + "@smithy/util-defaults-mode-node" "^3.0.30" + "@smithy/util-endpoints" "^2.1.7" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + "@smithy/util-utf8" "^3.0.0" + "@smithy/util-waiter" "^3.2.0" + "@types/uuid" "^9.0.1" + tslib "^2.6.2" + uuid "^9.0.1" + +"@aws-sdk/client-s3@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.709.0.tgz#ae27e18c5ced29f0d24857e4a28fb6947cdba3a4" + integrity sha512-IvC7coELoQ4YenTdULArVdL5yk6jNRVUALX1aqv9JlPdrXxb3Om6YrM9e7AlSTLxrULTsAe1ubm8i/DmcSY/Ng== + dependencies: + "@aws-crypto/sha1-browser" "5.2.0" + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/client-sso-oidc" "3.709.0" + "@aws-sdk/client-sts" "3.709.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/credential-provider-node" "3.709.0" + "@aws-sdk/middleware-bucket-endpoint" "3.709.0" + "@aws-sdk/middleware-expect-continue" "3.709.0" + "@aws-sdk/middleware-flexible-checksums" "3.709.0" + "@aws-sdk/middleware-host-header" "3.709.0" + "@aws-sdk/middleware-location-constraint" "3.709.0" + "@aws-sdk/middleware-logger" "3.709.0" + "@aws-sdk/middleware-recursion-detection" "3.709.0" + "@aws-sdk/middleware-sdk-s3" "3.709.0" + "@aws-sdk/middleware-ssec" "3.709.0" + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/region-config-resolver" "3.709.0" + "@aws-sdk/signature-v4-multi-region" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@aws-sdk/util-user-agent-browser" "3.709.0" + "@aws-sdk/util-user-agent-node" "3.709.0" + "@aws-sdk/xml-builder" "3.709.0" + "@smithy/config-resolver" "^3.0.13" + "@smithy/core" "^2.5.5" + "@smithy/eventstream-serde-browser" "^3.0.14" + "@smithy/eventstream-serde-config-resolver" "^3.0.11" + "@smithy/eventstream-serde-node" "^3.0.13" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/hash-blob-browser" "^3.1.10" + "@smithy/hash-node" "^3.0.11" + "@smithy/hash-stream-node" "^3.1.10" + "@smithy/invalid-dependency" "^3.0.11" + "@smithy/md5-js" "^3.0.11" + "@smithy/middleware-content-length" "^3.0.13" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-retry" "^3.0.30" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-body-length-node" "^3.0.0" + "@smithy/util-defaults-mode-browser" "^3.0.30" + "@smithy/util-defaults-mode-node" "^3.0.30" + "@smithy/util-endpoints" "^2.1.7" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + "@smithy/util-stream" "^3.3.2" + "@smithy/util-utf8" "^3.0.0" + "@smithy/util-waiter" "^3.2.0" + tslib "^2.6.2" + "@aws-sdk/client-s3@^3.388.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.693.0.tgz#188b621498ffaeb7b1ea5794f61e3e8d9a4bcac2" @@ -259,6 +374,51 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/client-sso-oidc@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.709.0.tgz#959e4df4070f1d059d8d0cd5b9028d9a46ac7ecf" + integrity sha512-1w6egz17QQy661lNCRmZZlqIANEbD6g2VFAQIJbVwSiu7brg+GUns+mT1eLLLHAMQc1sL0Ds8/ybSK2SrgGgIA== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/credential-provider-node" "3.709.0" + "@aws-sdk/middleware-host-header" "3.709.0" + "@aws-sdk/middleware-logger" "3.709.0" + "@aws-sdk/middleware-recursion-detection" "3.709.0" + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/region-config-resolver" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@aws-sdk/util-user-agent-browser" "3.709.0" + "@aws-sdk/util-user-agent-node" "3.709.0" + "@smithy/config-resolver" "^3.0.13" + "@smithy/core" "^2.5.5" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/hash-node" "^3.0.11" + "@smithy/invalid-dependency" "^3.0.11" + "@smithy/middleware-content-length" "^3.0.13" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-retry" "^3.0.30" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-body-length-node" "^3.0.0" + "@smithy/util-defaults-mode-browser" "^3.0.30" + "@smithy/util-defaults-mode-node" "^3.0.30" + "@smithy/util-endpoints" "^2.1.7" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@aws-sdk/client-sso@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz#9cd5e07e57013b8c7980512810d775d7b6f67e36" @@ -303,6 +463,50 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/client-sso@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.709.0.tgz#b5b29161e07af6f82afd7a6e750c09b0158d19e3" + integrity sha512-Qxeo8cN0jNy6Wnbqq4wucffAGJM6sJjofoTgNtPA6cC7sPYx7aYC6OAAAo6NaMRY+WywOKdS9Wgjx2QYRxKx7w== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/middleware-host-header" "3.709.0" + "@aws-sdk/middleware-logger" "3.709.0" + "@aws-sdk/middleware-recursion-detection" "3.709.0" + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/region-config-resolver" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@aws-sdk/util-user-agent-browser" "3.709.0" + "@aws-sdk/util-user-agent-node" "3.709.0" + "@smithy/config-resolver" "^3.0.13" + "@smithy/core" "^2.5.5" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/hash-node" "^3.0.11" + "@smithy/invalid-dependency" "^3.0.11" + "@smithy/middleware-content-length" "^3.0.13" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-retry" "^3.0.30" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-body-length-node" "^3.0.0" + "@smithy/util-defaults-mode-browser" "^3.0.30" + "@smithy/util-defaults-mode-node" "^3.0.30" + "@smithy/util-endpoints" "^2.1.7" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@aws-sdk/client-sts@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz#9e2c418f4850269635632bee4d1a31057c04bcc5" @@ -349,6 +553,52 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/client-sts@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.709.0.tgz#b9ad3c9c6419d0d149b28cdd6c115cc40c4e7906" + integrity sha512-cBAvlPg6yslXNL385UUGFPw+XY+lA9BzioNdIFkMo3fEUlTShogTtiWz4LsyLHoN6LhKojssP9DSmmWKWjCZIw== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/client-sso-oidc" "3.709.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/credential-provider-node" "3.709.0" + "@aws-sdk/middleware-host-header" "3.709.0" + "@aws-sdk/middleware-logger" "3.709.0" + "@aws-sdk/middleware-recursion-detection" "3.709.0" + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/region-config-resolver" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@aws-sdk/util-user-agent-browser" "3.709.0" + "@aws-sdk/util-user-agent-node" "3.709.0" + "@smithy/config-resolver" "^3.0.13" + "@smithy/core" "^2.5.5" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/hash-node" "^3.0.11" + "@smithy/invalid-dependency" "^3.0.11" + "@smithy/middleware-content-length" "^3.0.13" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-retry" "^3.0.30" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-body-length-node" "^3.0.0" + "@smithy/util-defaults-mode-browser" "^3.0.30" + "@smithy/util-defaults-mode-node" "^3.0.30" + "@smithy/util-endpoints" "^2.1.7" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@aws-sdk/core@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.693.0.tgz#437969dd740895a59863d737bad14646bc2e1725" @@ -366,6 +616,23 @@ fast-xml-parser "4.4.1" tslib "^2.6.2" +"@aws-sdk/core@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.709.0.tgz#d2b3d5b90f6614e3afc109ebdcaaedbb54c2d68b" + integrity sha512-7kuSpzdOTAE026j85wq/fN9UDZ70n0OHw81vFqMWwlEFtm5IQ/MRCLKcC4HkXxTdfy1PqFlmoXxWqeBa15tujw== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/core" "^2.5.5" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/property-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.8" + "@smithy/signature-v4" "^4.2.4" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/util-middleware" "^3.0.11" + fast-xml-parser "4.4.1" + tslib "^2.6.2" + "@aws-sdk/credential-provider-env@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.693.0.tgz#f97feed9809fe2800216943470015fdaaba47c4f" @@ -377,6 +644,17 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-env@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.709.0.tgz#a7f75375d8a413f9ab2bc42f743b943da6d3362d" + integrity sha512-ZMAp9LSikvHDFVa84dKpQmow6wsg956Um20cKuioPpX2GGreJFur7oduD+tRJT6FtIOHn+64YH+0MwiXLhsaIQ== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/property-provider" "^3.1.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-http@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz#5caad0ac47eded1edeb63f907280580ccfaadba3" @@ -393,6 +671,22 @@ "@smithy/util-stream" "^3.3.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-http@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.709.0.tgz#a378cbcc4cf373cc277944f1e84e9952f3884f5d" + integrity sha512-lIS7XLwCOyJnLD70f+VIRr8DNV1HPQe9oN6aguYrhoczqz7vDiVZLe3lh714cJqq9rdxzFypK5DqKHmcscMEPQ== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/property-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/util-stream" "^3.3.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-ini@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz#b4557ac1092657660a15c9bd55e17c27f79ec621" @@ -411,6 +705,24 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-ini@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.709.0.tgz#b01c68d98ce4cc48f79405234e32a9de2f943ea1" + integrity sha512-qCF8IIGcPoUp+Ib3ANhbF5gElxFd+kIrtv2/1tKdvhudMANstQbMiWV0LTH47ZZR6c3as4iSrm09NZnpEoD/pA== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/credential-provider-env" "3.709.0" + "@aws-sdk/credential-provider-http" "3.709.0" + "@aws-sdk/credential-provider-process" "3.709.0" + "@aws-sdk/credential-provider-sso" "3.709.0" + "@aws-sdk/credential-provider-web-identity" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/credential-provider-imds" "^3.2.8" + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-node@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz#c5ceac64a69304d5b4db3fd68473480cafddb4a9" @@ -429,6 +741,24 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-node@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.709.0.tgz#270a31aae394e6c8fe7d3fdd0b92e7c3a863b933" + integrity sha512-4HRX9KYWPSjO5O/Vg03YAsebKpvTjTvpK1n7zHYBmlLMBLxUrVsL1nNKKC5p2/7OW3RL8XR1ki3QkoV7kGRxUQ== + dependencies: + "@aws-sdk/credential-provider-env" "3.709.0" + "@aws-sdk/credential-provider-http" "3.709.0" + "@aws-sdk/credential-provider-ini" "3.709.0" + "@aws-sdk/credential-provider-process" "3.709.0" + "@aws-sdk/credential-provider-sso" "3.709.0" + "@aws-sdk/credential-provider-web-identity" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/credential-provider-imds" "^3.2.8" + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-process@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.693.0.tgz#e84e945f1a148f06ff697608d5309e73347e5aa9" @@ -441,6 +771,18 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-process@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.709.0.tgz#2521f810590f0874c54cc842d3d56f455a728325" + integrity sha512-IAC+jPlGQII6jhIylHOwh3RgSobqlgL59nw2qYTURr8hMCI0Z1p5y2ee646HTVt4WeCYyzUAXfxr6YI/Vitv+Q== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-sso@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz#72767389f533d9d17a14af63daaafcc8368ab43a" @@ -455,6 +797,20 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-sso@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.709.0.tgz#f0cb855eed86748ff0c9afa06b3a234fb04b3206" + integrity sha512-rYdTDOxazS2GdGScelsRK5CAkktRLCCdRjlwXaxrcW57j749hEqxcF5uTv9RD6WBwInfedcSywErNZB+hylQlg== + dependencies: + "@aws-sdk/client-sso" "3.709.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/token-providers" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/credential-provider-web-identity@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz#b6133b5ef9d3582e36e02e9c66766714ff672a11" @@ -466,6 +822,50 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-web-identity@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.709.0.tgz#c2b03541cb57ae4c7d6abdca98f99a6a56833ea6" + integrity sha512-2lbDfE0IQ6gma/7BB2JpkjW5G0wGe4AS0x80oybYAYYviJmUtIR3Cn2pXun6bnAWElt4wYKl4su7oC36rs5rNA== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/property-provider" "^3.1.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + +"@aws-sdk/endpoint-cache@3.693.0": + version "3.693.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/endpoint-cache/-/endpoint-cache-3.693.0.tgz#4b3f0bbc16dc2907e1b977e3d8ddfc7ba008fd12" + integrity sha512-/zK0ZZncBf5FbTfo8rJMcQIXXk4Ibhe5zEMiwFNivVPR2uNC0+oqfwXz7vjxwY0t6BPE3Bs4h9uFEz4xuGCY6w== + dependencies: + mnemonist "0.38.3" + tslib "^2.6.2" + +"@aws-sdk/lib-dynamodb@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.709.0.tgz#fd90b76bce67af1a3079524710f7bc19647829ad" + integrity sha512-piIyvQ1DhoUEosKmjGnMxLClUb9tv5rPPZfgh9J4MmSygsYbE9HvC3tstje0xUudVZjsmzZpNyibl/n0LA0gdQ== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/util-dynamodb" "3.709.0" + "@smithy/core" "^2.5.5" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + +"@aws-sdk/lib-storage@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.709.0.tgz#2b12e558880418c3348cbd8f1e4e7f8db424b7b7" + integrity sha512-TnP+QSsWdiaQYS5HuB3n9H947z49m6qSEv5fth4L9xinBldLepLyyF+cua3/GlagkWqpxcATISgR9pE1PB0mhQ== + dependencies: + "@smithy/abort-controller" "^3.1.9" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/smithy-client" "^3.5.0" + buffer "5.6.0" + events "3.3.0" + stream-browserify "3.0.0" + tslib "^2.6.2" + "@aws-sdk/middleware-bucket-endpoint@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.693.0.tgz#e4823a40935d34f5e58a4fbc830d8ff92e44fc99" @@ -479,6 +879,31 @@ "@smithy/util-config-provider" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/middleware-bucket-endpoint@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.709.0.tgz#a69bdebfebb7b5b174d3a396f2361f5025d168f4" + integrity sha512-03+tJOd7KIZOiqWH7Z8BOfQIWkKJgjcpKOJKZ6FR2KjWGUOE1G+bo11wF4UuHQ0RmpKnApt+pQghZmSnE7WEeg== + dependencies: + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-arn-parser" "3.693.0" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + "@smithy/util-config-provider" "^3.0.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-endpoint-discovery@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.709.0.tgz#d5866603f2515f0da2c84ead99cd25b806d8ee5b" + integrity sha512-6CSHoAy3sVBJdeGiBpoRqVHpqLPqv5QuDxKsEMHoGdbGATmffyn2whTFfo5hfRYsN9WPz/XxUX2iynqQCnlrzw== + dependencies: + "@aws-sdk/endpoint-cache" "3.693.0" + "@aws-sdk/types" "3.709.0" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-expect-continue@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.693.0.tgz#d8696cee9ebea1d973d8daf872fd913b41d62cf0" @@ -489,6 +914,16 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-expect-continue@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.709.0.tgz#a7fec776da9de32e15088badfc09d69118f5d5ab" + integrity sha512-Tbl/DFvE4rHl8lMb9IzetwK4tf5R3VeHZkvEXQalsWoK0tbEQ8kXWi7wAYO4qbE7bFVvaxKX+irjJjTxf3BrCQ== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-flexible-checksums@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.693.0.tgz#80f07802d98ff33a6899a09c59cf51aab426aaac" @@ -508,6 +943,25 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/middleware-flexible-checksums@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.709.0.tgz#f0fb543c2db724cb43bae215ff0aea942d06a967" + integrity sha512-wbYm9tkyCaqMeU82yjaXw7V5BxCSlSLNupENW63LC7Fvyo/aQzj6LjSMHcBpR2QwjBEhXCtF47L7aQ8SPTNhdw== + dependencies: + "@aws-crypto/crc32" "5.2.0" + "@aws-crypto/crc32c" "5.2.0" + "@aws-crypto/util" "5.2.0" + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/is-array-buffer" "^3.0.0" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-stream" "^3.3.2" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@aws-sdk/middleware-host-header@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz#69322909c0792df1e6be7c7fb5e2b6f76090a55c" @@ -518,6 +972,16 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-host-header@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.709.0.tgz#f44f5c62f9bd7e5a443603fed68143d2d9725219" + integrity sha512-8gQYCYAaIw4lOCd5WYdf15Y/61MgRsAnrb2eiTl+icMlUOOzl8aOl5iDwm/Idp0oHZTflwxM4XSvGXO83PRWcw== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-location-constraint@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.693.0.tgz#1856eaaad64d41d1f8fa53ced58a6c7cf5eccc6e" @@ -527,6 +991,15 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-location-constraint@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.709.0.tgz#4437d3d3cfbbdfca60664b1f237d600b94fd06a5" + integrity sha512-5YQWPXfZq7OE0jB2G0PP8K10GBod/YPJXb+1CfJS6FbQaglRoIm8KZmVEvJNnptSKyGtE62veeCcCQcfAUfFig== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-logger@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz#fc10294e6963f8e5d58ba1ededd891e999f544a9" @@ -536,6 +1009,15 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-logger@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.709.0.tgz#b9a0b016b7ae09cb502cc4faf45964d4b5745824" + integrity sha512-jDoGSccXv9zebnpUoisjWd5u5ZPIalrmm6TjvPzZ8UqzQt3Beiz0tnQwmxQD6KRc7ADweWP5Ntiqzbw9xpVajg== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-recursion-detection@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz#88a8157293775e7116707da26501da4b5e042f51" @@ -546,6 +1028,16 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-recursion-detection@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.709.0.tgz#d7dc253d4858d496caeb12dd6cddd87b250fb98b" + integrity sha512-PObL/wLr4lkfbQ0yXUWaoCWu/jcwfwZzCjsUiXW/H6hW9b/00enZxmx7OhtJYaR6xmh/Lcx5wbhIoDCbzdv0tw== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-sdk-s3@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.693.0.tgz#e0850854d5079f372786b2ccfe85729caa7a49d8" @@ -566,6 +1058,26 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@aws-sdk/middleware-sdk-s3@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.709.0.tgz#b6f22c77e64760869eb06255af58376f879742b2" + integrity sha512-FwtOG9t9xsLoLOQZ6qAdsWOjx9dsO6t28IjIDV1l6Ixiu2oC0Yks7goONjJUH0IDE4pDDDGzmuq0sn1XtHhheA== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-arn-parser" "3.693.0" + "@smithy/core" "^2.5.5" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/protocol-http" "^4.1.8" + "@smithy/signature-v4" "^4.2.4" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/util-config-provider" "^3.0.0" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-stream" "^3.3.2" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@aws-sdk/middleware-ssec@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.693.0.tgz#2ff779147d188090b3a6cda3ed12ca4085220a73" @@ -575,6 +1087,15 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-ssec@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.709.0.tgz#bbf5253cdce45ed2759a108fd924fff4b8e049d5" + integrity sha512-2muiLe7YkmlwZp2SKz+goZrDThGfRq3o0FcJF3Puc0XGmcEPEDjih537mCoTrGgcXNFlBc7YChd84r3t72ySaQ== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/middleware-user-agent@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz#4b55cfab3fc7e671b08e1ea63a98e45a1e13e6a5" @@ -588,6 +1109,19 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/middleware-user-agent@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.709.0.tgz#2a467f14b3f4a9270bcdfde32e3d4e38701aaafe" + integrity sha512-ooc9ZJvgkjPhi9q05XwSfNTXkEBEIfL4hleo5rQBKwHG3aTHvwOM7LLzhdX56QZVa6sorPBp6fwULuRDSqiQHw== + dependencies: + "@aws-sdk/core" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-endpoints" "3.709.0" + "@smithy/core" "^2.5.5" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/node-http-handler@^3.374.0": version "3.374.0" resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.374.0.tgz#8cd58b4d9814713e26034c12eabc119c113a5bc4" @@ -608,6 +1142,32 @@ "@smithy/util-middleware" "^3.0.9" tslib "^2.6.2" +"@aws-sdk/region-config-resolver@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.709.0.tgz#64547b333842e5804e1793e4d6d29578c0b34a68" + integrity sha512-/NoCAMEVKAg3kBKOrNtgOfL+ECt6nrl+L7q2SyYmrcY4tVCmwuECVqewQaHc03fTnJijfKLccw0Fj+6wOCnB6w== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/types" "^3.7.2" + "@smithy/util-config-provider" "^3.0.0" + "@smithy/util-middleware" "^3.0.11" + tslib "^2.6.2" + +"@aws-sdk/s3-request-presigner@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.709.0.tgz#d3c9d881158bdece69863be318d49e9d7d2c512f" + integrity sha512-WYmXU2ur/z6xBX9TcGwSWlSiS8rxrRl2f1HJXZzgSu9FWZ7fJssoQGvrk/w64wjNq1tEzKbd1iWXw9s9qexT3g== + dependencies: + "@aws-sdk/signature-v4-multi-region" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@aws-sdk/util-format-url" "3.709.0" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/protocol-http" "^4.1.8" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/signature-v4-multi-region@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.693.0.tgz#85bd90bb78be1a98d5a5ca41033cb0703146c2c4" @@ -620,6 +1180,18 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/signature-v4-multi-region@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.709.0.tgz#0c6f9d3e2978158163b63a4085356616237223c9" + integrity sha512-m0vhJEy6SLbjL11K9cHzX/ZhCIj//1GkTbYk2d4tTQFSuPyJEkjmoeHk9dYm2mJy0wH48j29OJadI1JUsR5bOw== + dependencies: + "@aws-sdk/middleware-sdk-s3" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/protocol-http" "^4.1.8" + "@smithy/signature-v4" "^4.2.4" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/token-providers@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz#5ce7d6aa7a3437d4abdc0dca1be47f5158d15c85" @@ -631,6 +1203,17 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/token-providers@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.709.0.tgz#56305ab187660a711fd172c329dc953ca754fa80" + integrity sha512-q5Ar6k71nci43IbULFgC8a89d/3EHpmd7HvBzqVGRcHnoPwh8eZDBfbBXKH83NGwcS1qPSRYiDbVfeWPm4/1jA== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/types@3.692.0", "@aws-sdk/types@^3.222.0": version "3.692.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.692.0.tgz#c8f6c75b6ad659865b72759796d4d92c1b72069b" @@ -639,6 +1222,14 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/types@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.709.0.tgz#f8d7ab07e253d3ed0e3b360e09fc67c7430a73b9" + integrity sha512-ArtLTMxgjf13Kfu3gWH3Ez9Q5TkDdcRZUofpKH3pMGB/C6KAbeSCtIIDKfoRTUABzyGlPyCrZdnFjKyH+ypIpg== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/util-arn-parser@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.693.0.tgz#8dae27eb822ab4f88be28bb3c0fc11f1f13d3948" @@ -646,6 +1237,13 @@ dependencies: tslib "^2.6.2" +"@aws-sdk/util-dynamodb@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-dynamodb/-/util-dynamodb-3.709.0.tgz#12ced0849ff8f1ac8a1921f97fdb57813f22ec14" + integrity sha512-rGr9+Po6Ma2BHV2hIhfXdn8hWxLtmgFzFRqqtxOlRRIDN55wkb2AYXz/ydzf4kgb+PzT8sQxtn6hf7pDkl+yAg== + dependencies: + tslib "^2.6.2" + "@aws-sdk/util-endpoints@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz#99f56f83fc25bdc3321f5871d6354abd56768891" @@ -656,6 +1254,26 @@ "@smithy/util-endpoints" "^2.1.5" tslib "^2.6.2" +"@aws-sdk/util-endpoints@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.709.0.tgz#32dfe339d78b699ada68392bbb3bec25441bae5c" + integrity sha512-Mbc7AtL5WGCTKC16IGeUTz+sjpC3ptBda2t0CcK0kMVw3THDdcSq6ZlNKO747cNqdbwUvW34oHteUiHv4/z88Q== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/types" "^3.7.2" + "@smithy/util-endpoints" "^2.1.7" + tslib "^2.6.2" + +"@aws-sdk/util-format-url@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-format-url/-/util-format-url-3.709.0.tgz#6ac420c297cae442f6d4065214eefc0d977e1a10" + integrity sha512-HGR11hx1KeFfoub/TACf+Yyal37lR85791Di2QPaElQThaqztLlppxale3EohKboOFf7Q/zvslJyM0fmgrlpQw== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/querystring-builder" "^3.0.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/util-locate-window@^3.0.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz#1160f6d055cf074ca198eb8ecf89b6311537ad6c" @@ -673,6 +1291,16 @@ bowser "^2.11.0" tslib "^2.6.2" +"@aws-sdk/util-user-agent-browser@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.709.0.tgz#ad6e867bdd348923ec10ddd6c37740ce0986cd8f" + integrity sha512-/rL2GasJzdTWUURCQKFldw2wqBtY4k4kCiA2tVZSKg3y4Ey7zO34SW8ebaeCE2/xoWOyLR2/etdKyphoo4Zrtg== + dependencies: + "@aws-sdk/types" "3.709.0" + "@smithy/types" "^3.7.2" + bowser "^2.11.0" + tslib "^2.6.2" + "@aws-sdk/util-user-agent-node@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz#b26c806faa2001d4fa1d515b146eeff411513dd9" @@ -684,6 +1312,17 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/util-user-agent-node@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.709.0.tgz#7ff5a508bcad49963a550acadcced43d7af9960d" + integrity sha512-trBfzSCVWy7ILgqhEXgiuM7hfRCw4F4a8IK90tjk9YL0jgoJ6eJuOp7+DfCtHJaygoBxD3cdMFkOu+lluFmGBA== + dependencies: + "@aws-sdk/middleware-user-agent" "3.709.0" + "@aws-sdk/types" "3.709.0" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@aws-sdk/xml-builder@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.693.0.tgz#709a46a3335b71144d9f7917a7cb3033b5a04e82" @@ -692,6 +1331,14 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" +"@aws-sdk/xml-builder@3.709.0": + version "3.709.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.709.0.tgz#5841faa1e78afcea064557a1a56709978b325758" + integrity sha512-2GPCwlNxeHspoK/Mc8nbk9cBOkSpp3j2SJUQmFnyQK6V/pR6II2oPRyZkMomug1Rc10hqlBHByMecq4zhV2uUw== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@azure/abort-controller@^1.0.0", "@azure/abort-controller@^1.0.4": version "1.1.0" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.1.0.tgz#788ee78457a55af8a1ad342acb182383d2119249" @@ -2088,47 +2735,6 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@3.2.26": - version "0.0.0" - dependencies: - "@budibase/nano" "10.1.5" - "@budibase/pouchdb-replication-stream" "1.2.11" - "@budibase/shared-core" "*" - "@budibase/types" "*" - "@techpass/passport-openidconnect" "0.3.3" - aws-cloudfront-sign "3.0.2" - aws-sdk "2.1692.0" - bcrypt "5.1.0" - bcryptjs "2.4.3" - bull "4.10.1" - correlation-id "4.0.0" - dd-trace "5.26.0" - dotenv "16.0.1" - google-auth-library "^8.0.1" - google-spreadsheet "npm:@budibase/google-spreadsheet@4.1.5" - ioredis "5.3.2" - joi "17.6.0" - jsonwebtoken "9.0.2" - knex "2.4.2" - koa-passport "^6.0.0" - koa-pino-logger "4.0.0" - lodash "4.17.21" - node-fetch "2.6.7" - passport-google-oauth "2.0.0" - passport-local "1.0.0" - passport-oauth2-refresh "^2.1.0" - pino "8.11.0" - pino-http "8.3.3" - posthog-node "4.0.1" - pouchdb "9.0.0" - pouchdb-find "9.0.0" - redlock "4.2.0" - rotating-file-stream "3.1.0" - sanitize-s3-objectkey "0.0.1" - semver "^7.5.4" - tar-fs "2.1.1" - uuid "^8.3.2" - "@budibase/handlebars-helpers@^0.13.2": version "0.13.2" resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.13.2.tgz#73ab51c464e91fd955b429017648e0257060db77" @@ -2172,15 +2778,15 @@ through2 "^2.0.0" "@budibase/pro@npm:@budibase/pro@latest": - version "3.2.26" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.26.tgz#3525535e07827ff820eefeeb94ad9e0e818ac698" - integrity sha512-+V04NbKSBN3Up6vcyBFFpecQ3MrJvVuXN74JE9yLj+KVxQXJ1kwCrMgea/XyJomSc72PWb9sQzXADWTe5i5STA== + version "3.2.28" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.28.tgz#59b5b37225715bb8fbf5b1c5c989140b10b58710" + integrity sha512-eDPeZpYFRZYQhCulcQAUwFoPk68c8+K9mIsB6QD3oMHmHTDA1P2ZcXvLNqDTIqHB94DqnWinqDf4hTuGYApgPA== dependencies: "@anthropic-ai/sdk" "^0.27.3" - "@budibase/backend-core" "3.2.26" - "@budibase/shared-core" "3.2.26" - "@budibase/string-templates" "3.2.26" - "@budibase/types" "3.2.26" + "@budibase/backend-core" "*" + "@budibase/shared-core" "*" + "@budibase/string-templates" "*" + "@budibase/types" "*" "@koa/router" "13.1.0" bull "4.10.1" dd-trace "5.26.0" @@ -2193,25 +2799,6 @@ scim-patch "^0.8.1" scim2-parse-filter "^0.2.8" -"@budibase/shared-core@3.2.26": - version "0.0.0" - dependencies: - "@budibase/types" "*" - cron-validate "1.4.5" - -"@budibase/string-templates@3.2.26": - version "0.0.0" - dependencies: - "@budibase/handlebars-helpers" "^0.13.2" - dayjs "^1.10.8" - handlebars "^4.7.8" - lodash.clonedeep "^4.5.0" - -"@budibase/types@3.2.26": - version "0.0.0" - dependencies: - scim-patch "^0.8.1" - "@bull-board/api@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-5.10.2.tgz#ae8ff6918b23897bf879a6ead3683f964374c4b3" @@ -4284,6 +4871,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/abort-controller@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-3.1.9.tgz#47d323f754136a489e972d7fd465d534d72fcbff" + integrity sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/chunked-blob-reader-native@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.1.tgz#39045ed278ee1b6f4c12715c7565678557274c29" @@ -4310,6 +4905,17 @@ "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" +"@smithy/config-resolver@^3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-3.0.13.tgz#653643a77a33d0f5907a5e7582353886b07ba752" + integrity sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg== + dependencies: + "@smithy/node-config-provider" "^3.1.12" + "@smithy/types" "^3.7.2" + "@smithy/util-config-provider" "^3.0.0" + "@smithy/util-middleware" "^3.0.11" + tslib "^2.6.2" + "@smithy/core@^2.5.2", "@smithy/core@^2.5.3": version "2.5.3" resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.3.tgz#1d5723f676b0d6ec08c515272f0ac03aa59fac72" @@ -4324,6 +4930,20 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@smithy/core@^2.5.5": + version "2.5.5" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.5.tgz#c75b15caee9e58c800db3e6b99e9e373532d394a" + integrity sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw== + dependencies: + "@smithy/middleware-serde" "^3.0.11" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + "@smithy/util-body-length-browser" "^3.0.0" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-stream" "^3.3.2" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/credential-provider-imds@^3.2.6", "@smithy/credential-provider-imds@^3.2.7": version "3.2.7" resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz#6eedf87ba0238723ec46d8ce0f18e276685a702d" @@ -4335,6 +4955,27 @@ "@smithy/url-parser" "^3.0.10" tslib "^2.6.2" +"@smithy/credential-provider-imds@^3.2.8": + version "3.2.8" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz#27ed2747074c86a7d627a98e56f324a65cba88de" + integrity sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw== + dependencies: + "@smithy/node-config-provider" "^3.1.12" + "@smithy/property-provider" "^3.1.11" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + tslib "^2.6.2" + +"@smithy/eventstream-codec@^3.1.10": + version "3.1.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz#0c1a3457e7a23b71cd71525ceb668f8569a84dad" + integrity sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ== + dependencies: + "@aws-crypto/crc32" "5.2.0" + "@smithy/types" "^3.7.2" + "@smithy/util-hex-encoding" "^3.0.0" + tslib "^2.6.2" + "@smithy/eventstream-codec@^3.1.9": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz#4271354e75e57d30771fca307da403896c657430" @@ -4354,6 +4995,23 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/eventstream-serde-browser@^3.0.14": + version "3.0.14" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz#0c3584c7cde2e210aacdfbbd2b57c1d7e2ca3b95" + integrity sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg== + dependencies: + "@smithy/eventstream-serde-universal" "^3.0.13" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + +"@smithy/eventstream-serde-config-resolver@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz#5edceba836debea165ea93145231036f6286d67c" + integrity sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/eventstream-serde-config-resolver@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz#5c0b2ae0bb8e11cfa77851098e46f7350047ec8d" @@ -4371,6 +5029,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/eventstream-serde-node@^3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz#5aebd7b553becee277e411a2b69f6af8c9d7b3a6" + integrity sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ== + dependencies: + "@smithy/eventstream-serde-universal" "^3.0.13" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/eventstream-serde-universal@^3.0.12": version "3.0.12" resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz#803d7beb29a3de4a64e91af97331a4654741c35f" @@ -4380,6 +5047,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/eventstream-serde-universal@^3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz#609c922ea14a0a3eed23a28ac110344c935704eb" + integrity sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw== + dependencies: + "@smithy/eventstream-codec" "^3.1.10" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/fetch-http-handler@^4.1.0", "@smithy/fetch-http-handler@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz#cead80762af4cdea11e7eeb627ea1c4835265dfa" @@ -4391,6 +5067,27 @@ "@smithy/util-base64" "^3.0.0" tslib "^2.6.2" +"@smithy/fetch-http-handler@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz#f034ff16416b37d92908a1381ef5fddbf4ef1879" + integrity sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA== + dependencies: + "@smithy/protocol-http" "^4.1.8" + "@smithy/querystring-builder" "^3.0.11" + "@smithy/types" "^3.7.2" + "@smithy/util-base64" "^3.0.0" + tslib "^2.6.2" + +"@smithy/hash-blob-browser@^3.1.10": + version "3.1.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.10.tgz#985e308189c2687a15004152b97506882ffb2b13" + integrity sha512-elwslXOoNunmfS0fh55jHggyhccobFkexLYC1ZeZ1xP2BTSrcIBaHV2b4xUQOdctrSNOpMqOZH1r2XzWTEhyfA== + dependencies: + "@smithy/chunked-blob-reader" "^4.0.0" + "@smithy/chunked-blob-reader-native" "^3.0.1" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/hash-blob-browser@^3.1.8": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.9.tgz#1f2c3ef6afbb0ce3e58a0129753850bb9267aae8" @@ -4401,6 +5098,16 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/hash-node@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.11.tgz#99e09ead3fc99c8cd7ca0f254ea0e35714f2a0d3" + integrity sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA== + dependencies: + "@smithy/types" "^3.7.2" + "@smithy/util-buffer-from" "^3.0.0" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/hash-node@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.10.tgz#93c857b4bff3a48884886440fd9772924887e592" @@ -4411,6 +5118,15 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@smithy/hash-stream-node@^3.1.10": + version "3.1.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.10.tgz#94716b4556f4ccf2807e605f47bb5b018ed7dfb0" + integrity sha512-olomK/jZQ93OMayW1zfTHwcbwBdhcZOHsyWyiZ9h9IXvc1mCD/VuvzbLb3Gy/qNJwI4MANPLctTp2BucV2oU/Q== + dependencies: + "@smithy/types" "^3.7.2" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/hash-stream-node@^3.1.8": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.9.tgz#97eb416811b7e7b9d036f0271588151b619759e9" @@ -4420,6 +5136,14 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@smithy/invalid-dependency@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz#8144d7b0af9d34ab5f672e1f674f97f8740bb9ae" + integrity sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/invalid-dependency@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz#8616dee555916c24dec3e33b1e046c525efbfee3" @@ -4442,6 +5166,15 @@ dependencies: tslib "^2.6.2" +"@smithy/md5-js@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.11.tgz#27e4dab616348ff94aed24dc75e4017c582df40f" + integrity sha512-3NM0L3i2Zm4bbgG6Ymi9NBcxXhryi3uE8fIfHJZIOfZVxOkGdjdgjR9A06SFIZCfnEIWKXZdm6Yq5/aPXFFhsQ== + dependencies: + "@smithy/types" "^3.7.2" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/md5-js@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.10.tgz#52ab927cf03cd1d24fed82d8ba936faf5632436e" @@ -4460,6 +5193,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/middleware-content-length@^3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz#6e08fe52739ac8fb3996088e0f8837e4b2ea187f" + integrity sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw== + dependencies: + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/middleware-endpoint@^3.2.2", "@smithy/middleware-endpoint@^3.2.3": version "3.2.3" resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz#7dd3df0052fc55891522631a7751e613b6efd68a" @@ -4474,6 +5216,20 @@ "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" +"@smithy/middleware-endpoint@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz#bdcfdf1f342cf933b0b8a709996f9a8fbb8148f4" + integrity sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg== + dependencies: + "@smithy/core" "^2.5.5" + "@smithy/middleware-serde" "^3.0.11" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + "@smithy/url-parser" "^3.0.11" + "@smithy/util-middleware" "^3.0.11" + tslib "^2.6.2" + "@smithy/middleware-retry@^3.0.26": version "3.0.27" resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz#2e4dda420178835cd2d416479505d313b601ba21" @@ -4489,6 +5245,21 @@ tslib "^2.6.2" uuid "^9.0.1" +"@smithy/middleware-retry@^3.0.30": + version "3.0.30" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.30.tgz#2580322d0d28ad782b5b8c07c150b14efdc3b2f9" + integrity sha512-6323RL2BvAR3VQpTjHpa52kH/iSHyxd/G9ohb2MkBk2Ucu+oMtRXT8yi7KTSIS9nb58aupG6nO0OlXnQOAcvmQ== + dependencies: + "@smithy/node-config-provider" "^3.1.12" + "@smithy/protocol-http" "^4.1.8" + "@smithy/service-error-classification" "^3.0.11" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-retry" "^3.0.11" + tslib "^2.6.2" + uuid "^9.0.1" + "@smithy/middleware-serde@^3.0.10", "@smithy/middleware-serde@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz#5f6c0b57b10089a21d355bd95e9b7d40378454d7" @@ -4497,6 +5268,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/middleware-serde@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz#c7d54e0add4f83e05c6878a011fc664e21022f12" + integrity sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/middleware-stack@^3.0.10", "@smithy/middleware-stack@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz#73e2fde5d151440844161773a17ee13375502baf" @@ -4505,6 +5284,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/middleware-stack@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz#453af2096924e4064d9da4e053cfdf65d9a36acc" + integrity sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/node-config-provider@^3.1.10", "@smithy/node-config-provider@^3.1.11": version "3.1.11" resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz#95feba85a5cb3de3fe9adfff1060b35fd556d023" @@ -4515,6 +5302,16 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/node-config-provider@^3.1.12": + version "3.1.12" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz#1b1d674fc83f943dc7b3017e37f16f374e878a6c" + integrity sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ== + dependencies: + "@smithy/property-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/node-http-handler@^1.0.2": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-1.1.0.tgz#887cee930b520e08043c9f41e463f8d8f5dae127" @@ -4537,6 +5334,17 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/node-http-handler@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz#b34685863b74dabdaf7860aa81b42d0d5437c7e0" + integrity sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA== + dependencies: + "@smithy/abort-controller" "^3.1.9" + "@smithy/protocol-http" "^4.1.8" + "@smithy/querystring-builder" "^3.0.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/property-provider@^3.1.10", "@smithy/property-provider@^3.1.9": version "3.1.10" resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.10.tgz#ae00447c1060c194c3e1b9475f7c8548a70f8486" @@ -4545,6 +5353,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/property-provider@^3.1.11": + version "3.1.11" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.11.tgz#161cf1c2a2ada361e417382c57f5ba6fbca8acad" + integrity sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/protocol-http@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-1.2.0.tgz#a554e4dabb14508f0bc2cdef9c3710e2b294be04" @@ -4561,6 +5377,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/protocol-http@^4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-4.1.8.tgz#0461758671335f65e8ff3fc0885ab7ed253819c9" + integrity sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/querystring-builder@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-1.1.0.tgz#de6306104640ade34e59be33949db6cc64aa9d7f" @@ -4579,6 +5403,15 @@ "@smithy/util-uri-escape" "^3.0.0" tslib "^2.6.2" +"@smithy/querystring-builder@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz#2ed04adbe725671824c5613d0d6f9376d791a909" + integrity sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg== + dependencies: + "@smithy/types" "^3.7.2" + "@smithy/util-uri-escape" "^3.0.0" + tslib "^2.6.2" + "@smithy/querystring-parser@^3.0.10": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz#62db744a1ed2cf90f4c08d2c73d365e033b4a11c" @@ -4587,6 +5420,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/querystring-parser@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz#9d3177ea19ce8462f18d9712b395239e1ca1f969" + integrity sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/service-error-classification@^3.0.10": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz#941c549daf0e9abb84d3def1d9e1e3f0f74f5ba6" @@ -4594,6 +5435,13 @@ dependencies: "@smithy/types" "^3.7.1" +"@smithy/service-error-classification@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz#d3d7fc0aacd2e60d022507367e55c7939e5bcb8a" + integrity sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog== + dependencies: + "@smithy/types" "^3.7.2" + "@smithy/shared-ini-file-loader@^3.1.10", "@smithy/shared-ini-file-loader@^3.1.11": version "3.1.11" resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz#0b4f98c4a66480956fbbefc4627c5dc09d891aea" @@ -4602,6 +5450,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/shared-ini-file-loader@^3.1.12": + version "3.1.12" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz#d98b1b663eb18935ce2cbc79024631d34f54042a" + integrity sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/signature-v4@^4.2.2": version "4.2.3" resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.3.tgz#abbca5e5fe9158422b3125b2956791a325a27f22" @@ -4616,6 +5472,20 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@smithy/signature-v4@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.4.tgz#3501d3d09fd82768867bfc00a7be4bad62f62f4d" + integrity sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA== + dependencies: + "@smithy/is-array-buffer" "^3.0.0" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + "@smithy/util-hex-encoding" "^3.0.0" + "@smithy/util-middleware" "^3.0.11" + "@smithy/util-uri-escape" "^3.0.0" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/smithy-client@^3.4.3", "@smithy/smithy-client@^3.4.4": version "3.4.4" resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.4.4.tgz#460870dc97d945fa2f390890359cf09d01131e0f" @@ -4629,6 +5499,19 @@ "@smithy/util-stream" "^3.3.1" tslib "^2.6.2" +"@smithy/smithy-client@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.5.0.tgz#65cff262801b009998c1196764ee69929ee06f8a" + integrity sha512-Y8FeOa7gbDfCWf7njrkoRATPa5eNLUEjlJS5z5rXatYuGkCb80LbHcu8AQR8qgAZZaNHCLyo2N+pxPsV7l+ivg== + dependencies: + "@smithy/core" "^2.5.5" + "@smithy/middleware-endpoint" "^3.2.5" + "@smithy/middleware-stack" "^3.0.11" + "@smithy/protocol-http" "^4.1.8" + "@smithy/types" "^3.7.2" + "@smithy/util-stream" "^3.3.2" + tslib "^2.6.2" + "@smithy/types@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.2.0.tgz#9dc65767b0ee3d6681704fcc67665d6fc9b6a34e" @@ -4643,6 +5526,13 @@ dependencies: tslib "^2.6.2" +"@smithy/types@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.7.2.tgz#05cb14840ada6f966de1bf9a9c7dd86027343e10" + integrity sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg== + dependencies: + tslib "^2.6.2" + "@smithy/url-parser@^3.0.10", "@smithy/url-parser@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.10.tgz#f389985a79766cff4a99af14979f01a17ce318da" @@ -4652,6 +5542,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/url-parser@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.11.tgz#e5f5ffabfb6230159167cf4cc970705fca6b8b2d" + integrity sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw== + dependencies: + "@smithy/querystring-parser" "^3.0.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/util-base64@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-3.0.0.tgz#f7a9a82adf34e27a72d0719395713edf0e493017" @@ -4709,6 +5608,17 @@ bowser "^2.11.0" tslib "^2.6.2" +"@smithy/util-defaults-mode-browser@^3.0.30": + version "3.0.30" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.30.tgz#6c0d95af3f15bef8f1fe3f6217cc4f5ba8df5554" + integrity sha512-nLuGmgfcr0gzm64pqF2UT4SGWVG8UGviAdayDlVzJPNa6Z4lqvpDzdRXmLxtOdEjVlTOEdpZ9dd3ZMMu488mzg== + dependencies: + "@smithy/property-provider" "^3.1.11" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + bowser "^2.11.0" + tslib "^2.6.2" + "@smithy/util-defaults-mode-node@^3.0.26": version "3.0.27" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz#a7248c9d9cb620827ab57ef9d1867bfe8aef42d0" @@ -4722,6 +5632,19 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/util-defaults-mode-node@^3.0.30": + version "3.0.30" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.30.tgz#33cdb02f90944b9ff221e2f8e0904a63ac1e335f" + integrity sha512-OD63eWoH68vp75mYcfYyuVH+p7Li/mY4sYOROnauDrtObo1cS4uWfsy/zhOTW8F8ZPxQC1ZXZKVxoxvMGUv2Ow== + dependencies: + "@smithy/config-resolver" "^3.0.13" + "@smithy/credential-provider-imds" "^3.2.8" + "@smithy/node-config-provider" "^3.1.12" + "@smithy/property-provider" "^3.1.11" + "@smithy/smithy-client" "^3.5.0" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/util-endpoints@^2.1.5": version "2.1.6" resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz#720cbd1a616ad7c099b77780f0cb0f1f9fc5d2df" @@ -4731,6 +5654,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/util-endpoints@^2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz#a088ebfab946a7219dd4763bfced82709894b82d" + integrity sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw== + dependencies: + "@smithy/node-config-provider" "^3.1.12" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/util-hex-encoding@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz#32938b33d5bf2a15796cd3f178a55b4155c535e6" @@ -4746,6 +5678,14 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/util-middleware@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-3.0.11.tgz#2ab5c17266b42c225e62befcffb048afa682b5bf" + integrity sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow== + dependencies: + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/util-retry@^3.0.10", "@smithy/util-retry@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.10.tgz#fc13e1b30e87af0cbecadf29ca83b171e2040440" @@ -4755,6 +5695,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/util-retry@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.11.tgz#d267e5ccb290165cee69732547fea17b695a7425" + integrity sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ== + dependencies: + "@smithy/service-error-classification" "^3.0.11" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@smithy/util-stream@^3.3.0", "@smithy/util-stream@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.3.1.tgz#a2636f435637ef90d64df2bb8e71cd63236be112" @@ -4769,6 +5718,20 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" +"@smithy/util-stream@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.3.2.tgz#daeea26397e8541cf2499ce65bf0b8d528cba421" + integrity sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg== + dependencies: + "@smithy/fetch-http-handler" "^4.1.2" + "@smithy/node-http-handler" "^3.3.2" + "@smithy/types" "^3.7.2" + "@smithy/util-base64" "^3.0.0" + "@smithy/util-buffer-from" "^3.0.0" + "@smithy/util-hex-encoding" "^3.0.0" + "@smithy/util-utf8" "^3.0.0" + tslib "^2.6.2" + "@smithy/util-uri-escape@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-1.1.0.tgz#a8c5edaf19c0efdb9b51661e840549cf600a1808" @@ -4808,6 +5771,15 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" +"@smithy/util-waiter@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-3.2.0.tgz#1e52f870e77d2e5572025f7606053e6ff00df93d" + integrity sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg== + dependencies: + "@smithy/abort-controller" "^3.1.9" + "@smithy/types" "^3.7.2" + tslib "^2.6.2" + "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" @@ -6112,6 +7084,11 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + "@types/webidl-conversions@*": version "7.0.0" resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" @@ -7520,6 +8497,14 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -10228,7 +11213,7 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== -events@^3.0.0, events@^3.3.0: +events@3.3.0, events@^3.0.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -11984,7 +12969,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -14808,6 +15793,13 @@ mlly@^1.1.0, mlly@^1.7.1: pkg-types "^1.1.1" ufo "^1.5.3" +mnemonist@0.38.3: + version "0.38.3" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.3.tgz#35ec79c1c1f4357cfda2fe264659c2775ccd7d9d" + integrity sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw== + dependencies: + obliterator "^1.6.1" + modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -15600,6 +16592,11 @@ object.values@^1.1.7: define-properties "^1.2.0" es-abstract "^1.22.1" +obliterator@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" + integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== + omggif@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -18645,6 +19642,14 @@ stoppable@^1.1.0: resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + stream-events@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" From 544efaed6ea222719dfd9cd5b5282aca6b836d20 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 12 Dec 2024 18:25:49 +0000 Subject: [PATCH 02/57] Finishing off async code changes from pre-signing changes. --- .../objectStore/buckets/tests/plugins.spec.ts | 28 +++++++++---------- packages/server/src/sdk/plugins/plugins.ts | 2 +- .../server/src/utilities/fileSystem/app.ts | 2 +- .../server/src/utilities/fileSystem/plugin.ts | 7 ++++- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts index fc2822314e..0906ea91c2 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts @@ -6,8 +6,8 @@ describe("plugins", () => { describe("enrichPluginURLs", () => { const plugin = structures.plugins.plugin() - function getEnrichedPluginUrls() { - const enriched = plugins.enrichPluginURLs([plugin])[0] + async function getEnrichedPluginUrls() { + const enriched = (await plugins.enrichPluginURLs([plugin]))[0] return { jsUrl: enriched.jsUrl!, iconUrl: enriched.iconUrl!, @@ -19,9 +19,9 @@ describe("plugins", () => { testEnv.singleTenant() }) - it("gets url with embedded minio", () => { + it("gets url with embedded minio", async () => { testEnv.withMinio() - const urls = getEnrichedPluginUrls() + const urls = await getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `/files/signed/plugins/${plugin.name}/plugin.min.js` ) @@ -30,9 +30,9 @@ describe("plugins", () => { ) }) - it("gets url with custom S3", () => { + it("gets url with custom S3", async () => { testEnv.withS3() - const urls = getEnrichedPluginUrls() + const urls = await getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `http://s3.example.com/plugins/${plugin.name}/plugin.min.js` ) @@ -41,9 +41,9 @@ describe("plugins", () => { ) }) - it("gets url with cloudfront + s3", () => { + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - const urls = getEnrichedPluginUrls() + const urls = await getEnrichedPluginUrls() // omit rest of signed params expect( urls.jsUrl.includes( @@ -65,8 +65,8 @@ describe("plugins", () => { it("gets url with embedded minio", async () => { testEnv.withMinio() - await testEnv.withTenant(tenantId => { - const urls = getEnrichedPluginUrls() + await testEnv.withTenant(async tenantId => { + const urls = await getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `/files/signed/plugins/${tenantId}/${plugin.name}/plugin.min.js` ) @@ -78,8 +78,8 @@ describe("plugins", () => { it("gets url with custom S3", async () => { testEnv.withS3() - await testEnv.withTenant(tenantId => { - const urls = getEnrichedPluginUrls() + await testEnv.withTenant(async tenantId => { + const urls = await getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `http://s3.example.com/plugins/${tenantId}/${plugin.name}/plugin.min.js` ) @@ -91,8 +91,8 @@ describe("plugins", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(tenantId => { - const urls = getEnrichedPluginUrls() + await testEnv.withTenant(async tenantId => { + const urls = await getEnrichedPluginUrls() // omit rest of signed params expect( urls.jsUrl.includes( diff --git a/packages/server/src/sdk/plugins/plugins.ts b/packages/server/src/sdk/plugins/plugins.ts index 63f2f22cd9..bff24dcef7 100644 --- a/packages/server/src/sdk/plugins/plugins.ts +++ b/packages/server/src/sdk/plugins/plugins.ts @@ -18,7 +18,7 @@ export async function fetch(type?: PluginType): Promise { }) ) let plugins = response.rows.map((row: any) => row.doc) as Plugin[] - plugins = objectStore.enrichPluginURLs(plugins) + plugins = await objectStore.enrichPluginURLs(plugins) if (type) { return plugins.filter((plugin: Plugin) => plugin.schema?.type === type) } else { diff --git a/packages/server/src/utilities/fileSystem/app.ts b/packages/server/src/utilities/fileSystem/app.ts index 9bd88ba0b1..642017d2da 100644 --- a/packages/server/src/utilities/fileSystem/app.ts +++ b/packages/server/src/utilities/fileSystem/app.ts @@ -78,7 +78,7 @@ export const getComponentLibraryManifest = async (library: string) => { resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path) } if (typeof resp !== "string") { - resp = resp.toString("utf8") + resp = resp.toString() } return JSON.parse(resp) } diff --git a/packages/server/src/utilities/fileSystem/plugin.ts b/packages/server/src/utilities/fileSystem/plugin.ts index 3e1e9bef4d..2949daef61 100644 --- a/packages/server/src/utilities/fileSystem/plugin.ts +++ b/packages/server/src/utilities/fileSystem/plugin.ts @@ -3,6 +3,7 @@ import { budibaseTempDir } from "../budibaseDir" import fs from "fs" import { join } from "path" import { objectStore } from "@budibase/backend-core" +import stream from "stream" const DATASOURCE_PATH = join(budibaseTempDir(), "datasource") const AUTOMATION_PATH = join(budibaseTempDir(), "automation") @@ -58,7 +59,11 @@ async function getPluginImpl(path: string, plugin: Plugin) { pluginKey ) - fs.writeFileSync(filename, pluginJs) + if (pluginJs instanceof stream.Readable) { + pluginJs.pipe(fs.createWriteStream(filename)) + } else { + fs.writeFileSync(filename, pluginJs) + } fs.writeFileSync(metadataName, hash) return require(filename) From 49dca3b7c96d248d534700811a16f45d61afd39b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 13:19:25 +0000 Subject: [PATCH 03/57] Some fixes for failing test cases. --- packages/backend-core/src/environment.ts | 2 +- packages/backend-core/src/objectStore/objectStore.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/src/environment.ts b/packages/backend-core/src/environment.ts index 954fdd4135..9a46758062 100644 --- a/packages/backend-core/src/environment.ts +++ b/packages/backend-core/src/environment.ts @@ -154,7 +154,7 @@ const environment = { MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY, MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY, AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN, - AWS_REGION: process.env.AWS_REGION, + AWS_REGION: process.env.AWS_REGION || "eu-west-1", MINIO_URL: process.env.MINIO_URL, MINIO_ENABLED: process.env.MINIO_ENABLED || 1, INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 6acf2e21ae..513ad03bb5 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -119,7 +119,7 @@ export function ObjectStore( // Normally a signed url will need to be generated with a specified host in mind. // To support dynamic hosts, e.g. some unknown self-hosted installation url, // use a predefined host. The host 'minio-service' is also forwarded to minio requests via nginx - config.endpoint = "minio-service" + config.endpoint = "http://minio-service" } else { config.endpoint = env.MINIO_URL } From 0f659635c75e55c2571bd80309b06f592c2dc460 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 14:02:24 +0000 Subject: [PATCH 04/57] Fixing mocked test case. --- .../src/api/routes/tests/static.spec.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/server/src/api/routes/tests/static.spec.ts b/packages/server/src/api/routes/tests/static.spec.ts index c2808603e9..872085c382 100644 --- a/packages/server/src/api/routes/tests/static.spec.ts +++ b/packages/server/src/api/routes/tests/static.spec.ts @@ -1,12 +1,10 @@ // Directly mock the AWS SDK -jest.mock("aws-sdk", () => ({ - S3: jest.fn(() => ({ - getSignedUrl: jest.fn( - (operation, params) => `http://example.com/${params.Bucket}/${params.Key}` - ), - upload: jest.fn(() => ({ Contents: {} })), - })), +jest.mock("@aws-sdk/s3-request-presigner", () => ({ + getSignedUrl: jest.fn(() => { + return `http://example.com` + }), })) +jest.mock("@aws-sdk/client-s3") import { Datasource, SourceName } from "@budibase/types" import { setEnv } from "../../../environment" @@ -77,7 +75,10 @@ describe("/static", () => { type: "datasource", name: "Test", source: SourceName.S3, - config: {}, + config: { + accessKeyId: "bb", + secretAccessKey: "bb", + }, }, }) }) @@ -91,7 +92,7 @@ describe("/static", () => { .set(config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - expect(res.body.signedUrl).toEqual("http://example.com/foo/bar") + expect(res.body.signedUrl).toEqual("http://example.com") expect(res.body.publicUrl).toEqual( `https://${bucket}.s3.eu-west-1.amazonaws.com/${key}` ) From bb5361135cd5d7692a03faa1ea7dd68195bbdaff Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 14:41:31 +0000 Subject: [PATCH 05/57] Fixing more test that rely on mocks. --- .../src/integrations/tests/aws-sdk.mock.ts | 76 ------------------- .../src/integrations/tests/dynamodb.spec.ts | 24 ++++-- .../server/src/integrations/tests/s3.spec.ts | 49 +++++++++++- 3 files changed, 66 insertions(+), 83 deletions(-) delete mode 100644 packages/server/src/integrations/tests/aws-sdk.mock.ts diff --git a/packages/server/src/integrations/tests/aws-sdk.mock.ts b/packages/server/src/integrations/tests/aws-sdk.mock.ts deleted file mode 100644 index 0422adfd3c..0000000000 --- a/packages/server/src/integrations/tests/aws-sdk.mock.ts +++ /dev/null @@ -1,76 +0,0 @@ -const response = (body: any, extra?: any) => () => ({ - promise: () => body, - ...extra, -}) - -class DocumentClient { - put = jest.fn(response({})) - query = jest.fn( - response({ - Items: [], - }) - ) - scan = jest.fn( - response({ - Items: [ - { - Name: "test", - }, - ], - }) - ) - get = jest.fn(response({})) - update = jest.fn(response({})) - delete = jest.fn(response({})) -} - -class S3 { - listObjects = jest.fn( - response({ - Contents: [], - }) - ) - createBucket = jest.fn( - response({ - Contents: {}, - }) - ) - deleteObjects = jest.fn( - response({ - Contents: {}, - }) - ) - getSignedUrl = jest.fn((operation, params) => { - return `http://example.com/${params.Bucket}/${params.Key}` - }) - headBucket = jest.fn( - response({ - Contents: {}, - }) - ) - upload = jest.fn( - response({ - Contents: {}, - }) - ) - getObject = jest.fn( - response( - { - Body: "", - }, - { - createReadStream: jest.fn().mockReturnValue("stream"), - } - ) - ) -} - -module.exports = { - DynamoDB: { - DocumentClient, - }, - S3, - config: { - update: jest.fn(), - }, -} diff --git a/packages/server/src/integrations/tests/dynamodb.spec.ts b/packages/server/src/integrations/tests/dynamodb.spec.ts index c992bc8bfd..75fb84ae60 100644 --- a/packages/server/src/integrations/tests/dynamodb.spec.ts +++ b/packages/server/src/integrations/tests/dynamodb.spec.ts @@ -1,4 +1,20 @@ -jest.mock("aws-sdk", () => require("./aws-sdk.mock")) +jest.mock("@aws-sdk/lib-dynamodb", () => ({ + DynamoDBDocument: { + from: jest.fn(() => ({ + update: jest.fn(), + put: jest.fn(), + query: jest.fn(() => ({ + Items: [], + })), + scan: jest.fn(() => ({ + Items: [], + })), + delete: jest.fn(), + get: jest.fn(), + })), + }, +})) +jest.mock("@aws-sdk/client-dynamodb") import { default as DynamoDBIntegration } from "../dynamodb" class TestConfiguration { @@ -57,11 +73,7 @@ describe("DynamoDB Integration", () => { TableName: tableName, IndexName: indexName, }) - expect(response).toEqual([ - { - Name: "test", - }, - ]) + expect(response).toEqual([]) }) it("calls the get method with the correct params", async () => { diff --git a/packages/server/src/integrations/tests/s3.spec.ts b/packages/server/src/integrations/tests/s3.spec.ts index abe8fb9cf1..678f15bf17 100644 --- a/packages/server/src/integrations/tests/s3.spec.ts +++ b/packages/server/src/integrations/tests/s3.spec.ts @@ -1,5 +1,52 @@ -jest.mock("aws-sdk", () => require("./aws-sdk.mock")) import { default as S3Integration } from "../s3" +jest.mock("@aws-sdk/client-s3", () => { + class S3Mock { + response(body: any, extra?: any) { + return () => ({ + promise: () => body, + ...extra, + }) + } + + listObjects = jest.fn( + this.response({ + Contents: [], + }) + ) + createBucket = jest.fn( + this.response({ + Contents: {}, + }) + ) + deleteObjects = jest.fn( + this.response({ + Contents: {}, + }) + ) + headBucket = jest.fn( + this.response({ + Contents: {}, + }) + ) + upload = jest.fn( + this.response({ + Contents: {}, + }) + ) + getObject = jest.fn( + this.response( + { + Body: "", + }, + { + createReadStream: jest.fn().mockReturnValue("stream"), + } + ) + ) + } + + return { S3: S3Mock } +}) class TestConfiguration { integration: any From cd2286e8cb55c19fe2112e05c6e2b895d1325497 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 14:49:57 +0000 Subject: [PATCH 06/57] removing some extra .promise calls. --- .../src/objectStore/objectStore.ts | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 513ad03bb5..adc974a131 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -138,30 +138,25 @@ export async function createBucketIfNotExists( ): Promise<{ created: boolean; exists: boolean }> { bucketName = sanitizeBucket(bucketName) try { - await // The `.promise()` call might be on an JS SDK v2 client API. - // If yes, please remove .promise(). If not, remove this comment. - client - .headBucket({ - Bucket: bucketName, - }) - .promise() + await client.headBucket({ + Bucket: bucketName, + }) return { created: false, exists: true } } catch (err: any) { - const promises: any = STATE.bucketCreationPromises - const doesntExist = err.statusCode === 404, - noAccess = err.statusCode === 403 + const statusCode = err.statusCode || err.$response?.statusCode + const promises: Record | undefined> = + STATE.bucketCreationPromises + const doesntExist = statusCode === 404, + noAccess = statusCode === 403 if (promises[bucketName]) { await promises[bucketName] return { created: false, exists: true } } else if (doesntExist || noAccess) { if (doesntExist) { - promises[bucketName] = // The `.promise()` call might be on an JS SDK v2 client API. - // If yes, please remove .promise(). If not, remove this comment. - client - .createBucket({ - Bucket: bucketName, - }) - .promise() + promises[bucketName] = client.createBucket({ + Bucket: bucketName, + }) + await promises[bucketName] delete promises[bucketName] return { created: true, exists: false } @@ -474,10 +469,7 @@ export async function deleteFolder( Prefix: folder, } - const existingObjectsResponse = - await // The `.promise()` call might be on an JS SDK v2 client API. - // If yes, please remove .promise(). If not, remove this comment. - client.listObjects(listParams) + const existingObjectsResponse = await client.listObjects(listParams) if (existingObjectsResponse.Contents?.length === 0) { return } From 5b4f71ca08fa4090bac2952f4edc769eb33d91b7 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 15:13:19 +0000 Subject: [PATCH 07/57] Fixing mocks in backend-core. --- .../__mocks__/@aws-sdk/client-s3.ts | 33 +++++++++++++++++ .../@aws-sdk/s3-request-presigner.ts | 1 + packages/backend-core/__mocks__/aws-sdk.ts | 19 ---------- .../src/objectStore/buckets/tests/app.spec.ts | 36 ------------------- 4 files changed, 34 insertions(+), 55 deletions(-) create mode 100644 packages/backend-core/__mocks__/@aws-sdk/client-s3.ts create mode 100644 packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts delete mode 100644 packages/backend-core/__mocks__/aws-sdk.ts diff --git a/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts b/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts new file mode 100644 index 0000000000..f93b493493 --- /dev/null +++ b/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts @@ -0,0 +1,33 @@ +export class S3 { + headBucket() { + return jest.fn().mockReturnThis() + } + deleteObject() { + return jest.fn().mockReturnThis() + } + deleteObjects() { + return jest.fn().mockReturnThis() + } + createBucket() { + return jest.fn().mockReturnThis() + } + getObject() { + return jest.fn().mockReturnThis() + } + listObject() { + return jest.fn().mockReturnThis() + } + getSignedUrl() { + return jest.fn((operation: string, params: any) => { + return `http://s3.example.com/${params.Bucket}/${params.Key}` + }) + } + promise() { + return jest.fn().mockReturnThis() + } + catch() { + return jest.fn() + } +} + +export const GetObjectCommand = jest.fn() diff --git a/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts b/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts new file mode 100644 index 0000000000..1a39fd96ae --- /dev/null +++ b/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts @@ -0,0 +1 @@ +export const getSignedUrl = jest.fn(() => "http://localhost:10000") diff --git a/packages/backend-core/__mocks__/aws-sdk.ts b/packages/backend-core/__mocks__/aws-sdk.ts deleted file mode 100644 index e3be511d08..0000000000 --- a/packages/backend-core/__mocks__/aws-sdk.ts +++ /dev/null @@ -1,19 +0,0 @@ -const mockS3 = { - headBucket: jest.fn().mockReturnThis(), - deleteObject: jest.fn().mockReturnThis(), - deleteObjects: jest.fn().mockReturnThis(), - createBucket: jest.fn().mockReturnThis(), - getObject: jest.fn().mockReturnThis(), - listObject: jest.fn().mockReturnThis(), - getSignedUrl: jest.fn((operation: string, params: any) => { - return `http://s3.example.com/${params.Bucket}/${params.Key}` - }), - promise: jest.fn().mockReturnThis(), - catch: jest.fn(), -} - -const AWS = { - S3: jest.fn(() => mockS3), -} - -export default AWS diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index 1aeba8f2c2..d188d774bb 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -93,22 +93,6 @@ describe("app", () => { testEnv.multiTenant() }) - it("gets url with embedded minio", () => { - testEnv.withMinio() - const url = getAppFileUrl() - expect(url).toBe( - "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" - ) - }) - - it("gets url with custom S3", () => { - testEnv.withS3() - const url = getAppFileUrl() - expect(url).toBe( - "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" - ) - }) - it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getAppFileUrl() @@ -124,26 +108,6 @@ describe("app", () => { testEnv.multiTenant() }) - it("gets url with embedded minio", async () => { - testEnv.withMinio() - await testEnv.withTenant(() => { - const url = getAppFileUrl() - expect(url).toBe( - "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" - ) - }) - }) - - it("gets url with custom S3", async () => { - testEnv.withS3() - await testEnv.withTenant(() => { - const url = getAppFileUrl() - expect(url).toBe( - "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" - ) - }) - }) - it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async () => { From 6e6c3c7bacb10a6b226307ec268e41fbaa7a5989 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 15:32:54 +0000 Subject: [PATCH 08/57] Fixing another test depending on mock behaviour. --- .../objectStore/buckets/tests/global.spec.ts | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index be459a7a23..9d5ec07c7a 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -3,7 +3,7 @@ import { testEnv } from "../../../../tests/extra" describe("global", () => { describe("getGlobalFileUrl", () => { - function getGlobalFileUrl() { + async function getGlobalFileUrl() { return global.getGlobalFileUrl("settings", "logoUrl", "etag") } @@ -12,18 +12,6 @@ describe("global", () => { testEnv.singleTenant() }) - it("gets url with embedded minio", () => { - testEnv.withMinio() - const url = getGlobalFileUrl() - expect(url).toBe("/files/signed/global/settings/logoUrl") - }) - - it("gets url with custom S3", () => { - testEnv.withS3() - const url = getGlobalFileUrl() - expect(url).toBe("http://s3.example.com/global/settings/logoUrl") - }) - it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getGlobalFileUrl() @@ -39,24 +27,6 @@ describe("global", () => { testEnv.multiTenant() }) - it("gets url with embedded minio", async () => { - testEnv.withMinio() - await testEnv.withTenant(tenantId => { - const url = getGlobalFileUrl() - expect(url).toBe(`/files/signed/global/${tenantId}/settings/logoUrl`) - }) - }) - - it("gets url with custom S3", async () => { - testEnv.withS3() - await testEnv.withTenant(tenantId => { - const url = getGlobalFileUrl() - expect(url).toBe( - `http://s3.example.com/global/${tenantId}/settings/logoUrl` - ) - }) - }) - it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async tenantId => { From f9e144f25cd70dfc61e5bb17e39b55eb2b1be276 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 19 Dec 2024 15:43:04 +0000 Subject: [PATCH 09/57] Updating mocks. --- packages/backend-core/__mocks__/@aws-sdk/client-s3.ts | 7 +------ .../__mocks__/@aws-sdk/s3-request-presigner.ts | 5 ++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts b/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts index f93b493493..8f002f41a8 100644 --- a/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts +++ b/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts @@ -17,11 +17,6 @@ export class S3 { listObject() { return jest.fn().mockReturnThis() } - getSignedUrl() { - return jest.fn((operation: string, params: any) => { - return `http://s3.example.com/${params.Bucket}/${params.Key}` - }) - } promise() { return jest.fn().mockReturnThis() } @@ -30,4 +25,4 @@ export class S3 { } } -export const GetObjectCommand = jest.fn() +export const GetObjectCommand = jest.fn(inputs => ({ inputs })) diff --git a/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts b/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts index 1a39fd96ae..3ed2c10595 100644 --- a/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts +++ b/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts @@ -1 +1,4 @@ -export const getSignedUrl = jest.fn(() => "http://localhost:10000") +export const getSignedUrl = jest.fn((_, cmd) => { + const { inputs } = cmd + return `http://s3.example.com/${inputs?.Bucket}/${inputs?.Key}` +}) From fbeb15d18656701c9d3f5ab9716579d6ee196758 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 20 Dec 2024 14:00:59 +0000 Subject: [PATCH 10/57] Updating hover and navigation stores. --- .../src/stores/builder/{hover.js => hover.ts} | 13 ++++++--- .../builder/{navigation.js => navigation.ts} | 29 +++++++++---------- packages/types/src/documents/app/app.ts | 8 +++-- packages/types/src/ui/stores/index.ts | 1 + packages/types/src/ui/stores/misc.ts | 2 ++ 5 files changed, 31 insertions(+), 22 deletions(-) rename packages/builder/src/stores/builder/{hover.js => hover.ts} (73%) rename packages/builder/src/stores/builder/{navigation.js => navigation.ts} (73%) create mode 100644 packages/types/src/ui/stores/misc.ts diff --git a/packages/builder/src/stores/builder/hover.js b/packages/builder/src/stores/builder/hover.ts similarity index 73% rename from packages/builder/src/stores/builder/hover.js rename to packages/builder/src/stores/builder/hover.ts index 8da7191cf5..aec8eed1cd 100644 --- a/packages/builder/src/stores/builder/hover.js +++ b/packages/builder/src/stores/builder/hover.ts @@ -2,19 +2,24 @@ import { get } from "svelte/store" import { previewStore } from "stores/builder" import { BudiStore } from "../BudiStore" +interface BuilderHoverStore { + hoverTimeout?: NodeJS.Timeout + componentId: string | null +} + export const INITIAL_HOVER_STATE = { componentId: null, } -export class HoverStore extends BudiStore { - hoverTimeout +export class HoverStore extends BudiStore { + hoverTimeout?: NodeJS.Timeout constructor() { super({ ...INITIAL_HOVER_STATE }) this.hover = this.hover.bind(this) } - hover(componentId, notifyClient = true) { + hover(componentId: string, notifyClient = true) { clearTimeout(this.hoverTimeout) if (componentId) { this.processHover(componentId, notifyClient) @@ -25,7 +30,7 @@ export class HoverStore extends BudiStore { } } - processHover(componentId, notifyClient) { + processHover(componentId: string, notifyClient?: boolean) { if (componentId === get(this.store).componentId) { return } diff --git a/packages/builder/src/stores/builder/navigation.js b/packages/builder/src/stores/builder/navigation.ts similarity index 73% rename from packages/builder/src/stores/builder/navigation.js rename to packages/builder/src/stores/builder/navigation.ts index abdd9638f3..f623224f4d 100644 --- a/packages/builder/src/stores/builder/navigation.js +++ b/packages/builder/src/stores/builder/navigation.ts @@ -2,27 +2,22 @@ import { get } from "svelte/store" import { API } from "api" import { appStore } from "stores/builder" import { BudiStore } from "../BudiStore" +import { AppNavigation, AppNavigationLink, UIObject } from "@budibase/types" + +interface BuilderNavigationStore extends AppNavigation {} export const INITIAL_NAVIGATION_STATE = { navigation: "Top", links: [], - title: null, - sticky: null, - hideLogo: null, - logoUrl: null, - hideTitle: null, textAlign: "Left", - navBackground: null, - navWidth: null, - navTextColor: null, } -export class NavigationStore extends BudiStore { +export class NavigationStore extends BudiStore { constructor() { super(INITIAL_NAVIGATION_STATE) } - syncAppNavigation(nav) { + syncAppNavigation(nav: AppNavigation) { this.update(state => ({ ...state, ...nav, @@ -33,15 +28,17 @@ export class NavigationStore extends BudiStore { this.store.set({ ...INITIAL_NAVIGATION_STATE }) } - async save(navigation) { + async save(navigation: AppNavigation) { const appId = get(appStore).appId const app = await API.saveAppMetadata(appId, { navigation }) - this.syncAppNavigation(app.navigation) + if (app.navigation) { + this.syncAppNavigation(app.navigation) + } } - async saveLink(url, title, roleId) { + async saveLink(url: string, title: string, roleId: string) { const navigation = get(this.store) - let links = [...(navigation?.links ?? [])] + let links: AppNavigationLink[] = [...(navigation?.links ?? [])] // Skip if we have an identical link if (links.find(link => link.url === url && link.text === title)) { @@ -60,7 +57,7 @@ export class NavigationStore extends BudiStore { }) } - async deleteLink(urls) { + async deleteLink(urls: string[] | string) { const navigation = get(this.store) let links = navigation?.links if (!links?.length) { @@ -86,7 +83,7 @@ export class NavigationStore extends BudiStore { }) } - syncMetadata(metadata) { + syncMetadata(metadata: UIObject) { const { navigation } = metadata this.syncAppNavigation(navigation) } diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index e31dd1e9ac..a316ce173c 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -1,5 +1,6 @@ import { User, Document, Plugin, Snippet } from "../" import { SocketSession } from "../../sdk" +import { NavLink } from "../../ui" export type AppMetadataErrors = { [key: string]: string[] } @@ -37,8 +38,8 @@ export interface AppInstance { export interface AppNavigation { navigation: string - title: string - navWidth: string + title?: string + navWidth?: string sticky?: boolean hideLogo?: boolean logoUrl?: string @@ -46,6 +47,7 @@ export interface AppNavigation { navBackground?: string navTextColor?: string links?: AppNavigationLink[] + textAlign?: string } export interface AppNavigationLink { @@ -53,6 +55,8 @@ export interface AppNavigationLink { url: string id?: string roleId?: string + type?: string + subLinks?: AppNavigationLink[] } export interface AppCustomTheme { diff --git a/packages/types/src/ui/stores/index.ts b/packages/types/src/ui/stores/index.ts index 658691cc6d..f3f6a96296 100644 --- a/packages/types/src/ui/stores/index.ts +++ b/packages/types/src/ui/stores/index.ts @@ -1 +1,2 @@ export * from "./integration" +export * from "./misc" diff --git a/packages/types/src/ui/stores/misc.ts b/packages/types/src/ui/stores/misc.ts new file mode 100644 index 0000000000..275b388e9f --- /dev/null +++ b/packages/types/src/ui/stores/misc.ts @@ -0,0 +1,2 @@ +// type purely to capture structures that the type is unknown, but maybe known later +export type UIObject = Record From ace8c68a264413ef83ca25264a18538575f4a545 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 20 Dec 2024 14:10:06 +0000 Subject: [PATCH 11/57] Lint. --- packages/types/src/documents/app/app.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index a316ce173c..e253aab225 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -1,6 +1,5 @@ import { User, Document, Plugin, Snippet } from "../" import { SocketSession } from "../../sdk" -import { NavLink } from "../../ui" export type AppMetadataErrors = { [key: string]: string[] } From fa06f7b6e8f0911f5bb0d3d0a7a96f2795fac3a3 Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 2 Jan 2025 10:29:39 +0000 Subject: [PATCH 12/57] Minor bug fix to ensure getPathSteps builds correctly. This will fix the test details --- packages/builder/src/stores/builder/automations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/stores/builder/automations.ts b/packages/builder/src/stores/builder/automations.ts index c43a856cc4..9b20b4cd03 100644 --- a/packages/builder/src/stores/builder/automations.ts +++ b/packages/builder/src/stores/builder/automations.ts @@ -291,8 +291,8 @@ const automationActions = (store: AutomationStore) => ({ let result: (AutomationStep | AutomationTrigger)[] = [] pathWay.forEach(path => { const { stepIdx, branchIdx } = path - let last = result ? result[result.length - 1] : [] - if (!result) { + let last = result.length ? result[result.length - 1] : [] + if (!result.length) { // Preceeding steps. result = steps.slice(0, stepIdx + 1) return From 8047ff99c6a7685b84d432d82ee80ef5cd9b2468 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 10:59:14 +0000 Subject: [PATCH 13/57] Flags / Layout / Preview stores to TS --- packages/builder/src/stores/builder/flags.js | 27 ------ packages/builder/src/stores/builder/flags.ts | 41 +++++++++ .../stores/builder/{layouts.js => layouts.ts} | 20 +++-- .../builder/src/stores/builder/preview.js | 80 ----------------- .../builder/src/stores/builder/preview.ts | 90 +++++++++++++++++++ 5 files changed, 144 insertions(+), 114 deletions(-) delete mode 100644 packages/builder/src/stores/builder/flags.js create mode 100644 packages/builder/src/stores/builder/flags.ts rename packages/builder/src/stores/builder/{layouts.js => layouts.ts} (77%) delete mode 100644 packages/builder/src/stores/builder/preview.js create mode 100644 packages/builder/src/stores/builder/preview.ts diff --git a/packages/builder/src/stores/builder/flags.js b/packages/builder/src/stores/builder/flags.js deleted file mode 100644 index 21236ffb01..0000000000 --- a/packages/builder/src/stores/builder/flags.js +++ /dev/null @@ -1,27 +0,0 @@ -import { writable } from "svelte/store" -import { API } from "@/api" - -export function createFlagsStore() { - const { subscribe, set } = writable({}) - - const actions = { - fetch: async () => { - const flags = await API.getFlags() - set(flags) - }, - updateFlag: async (flag, value) => { - await API.updateFlag(flag, value) - await actions.fetch() - }, - toggleUiFeature: async feature => { - await API.toggleUiFeature(feature) - }, - } - - return { - subscribe, - ...actions, - } -} - -export const flags = createFlagsStore() diff --git a/packages/builder/src/stores/builder/flags.ts b/packages/builder/src/stores/builder/flags.ts new file mode 100644 index 0000000000..cff3ac4d12 --- /dev/null +++ b/packages/builder/src/stores/builder/flags.ts @@ -0,0 +1,41 @@ +import { get } from "svelte/store" +import { API } from "@/api" +import { GetUserFlagsResponse } from "@budibase/types" +import { BudiStore } from "../BudiStore" + +interface FlagsState { + flags: GetUserFlagsResponse +} + +const INITIAL_FLAGS_STATE: FlagsState = { + flags: {}, +} + +export class FlagsStore extends BudiStore { + constructor() { + super(INITIAL_FLAGS_STATE) + + this.fetch = this.fetch.bind(this) + this.updateFlag = this.updateFlag.bind(this) + this.toggleUiFeature = this.toggleUiFeature.bind(this) + } + + async fetch() { + const flags = await API.getFlags() + this.update(state => ({ + ...state, + flags, + })) + } + + async updateFlag(flag: string, value: any) { + await API.updateFlag(flag, value) + await this.fetch() + } + + async toggleUiFeature(feature: string) { + await API.toggleUiFeature(feature) + } +} + +export const flags = new FlagsStore() diff --git a/packages/builder/src/stores/builder/layouts.js b/packages/builder/src/stores/builder/layouts.ts similarity index 77% rename from packages/builder/src/stores/builder/layouts.js rename to packages/builder/src/stores/builder/layouts.ts index 7617e203f0..0fd8efc8c0 100644 --- a/packages/builder/src/stores/builder/layouts.js +++ b/packages/builder/src/stores/builder/layouts.ts @@ -2,13 +2,19 @@ import { derived, get } from "svelte/store" import { componentStore } from "@/stores/builder" import { API } from "@/api" import { BudiStore } from "../BudiStore" +import { Layout } from "@budibase/types" -export const INITIAL_LAYOUT_STATE = { +interface LayoutState { + layouts: Layout[] + selectedLayoutId: string | null +} + +export const INITIAL_LAYOUT_STATE: LayoutState = { layouts: [], selectedLayoutId: null, } -export class LayoutStore extends BudiStore { +export class LayoutStore extends BudiStore { constructor() { super(INITIAL_LAYOUT_STATE) @@ -22,14 +28,14 @@ export class LayoutStore extends BudiStore { this.store.set({ ...INITIAL_LAYOUT_STATE }) } - syncAppLayouts(pkg) { + syncAppLayouts(pkg: { layouts: Layout[] }) { this.update(state => ({ ...state, layouts: [...pkg.layouts], })) } - select(layoutId) { + select(layoutId: string) { // Check this layout exists const state = get(this.store) const componentState = get(componentStore) @@ -48,18 +54,18 @@ export class LayoutStore extends BudiStore { // Select new layout this.update(state => { - state.selectedLayoutId = layout._id + state.selectedLayoutId = layout._id! return state }) componentStore.select(layout.props?._id) } - async deleteLayout(layout) { + async deleteLayout(layout: Layout) { if (!layout?._id) { return } - await API.deleteLayout(layout._id, layout._rev) + await API.deleteLayout(layout._id, layout._rev!) this.update(state => { state.layouts = state.layouts.filter(x => x._id !== layout._id) return state diff --git a/packages/builder/src/stores/builder/preview.js b/packages/builder/src/stores/builder/preview.js deleted file mode 100644 index 4923185ee7..0000000000 --- a/packages/builder/src/stores/builder/preview.js +++ /dev/null @@ -1,80 +0,0 @@ -import { writable, get } from "svelte/store" - -const INITIAL_PREVIEW_STATE = { - previewDevice: "desktop", - previewEventHandler: null, - showPreview: false, - selectedComponentContext: null, -} - -export const createPreviewStore = () => { - const store = writable({ - ...INITIAL_PREVIEW_STATE, - }) - - const setDevice = device => { - store.update(state => { - state.previewDevice = device - return state - }) - } - - // Potential evt names "eject-block", "dragging-new-component" - const sendEvent = (name, payload) => { - const { previewEventHandler } = get(store) - previewEventHandler?.(name, payload) - } - - const registerEventHandler = handler => { - store.update(state => { - state.previewEventHandler = handler - return state - }) - } - - const startDrag = component => { - sendEvent("dragging-new-component", { - dragging: true, - component, - }) - } - - const stopDrag = () => { - sendEvent("dragging-new-component", { - dragging: false, - }) - } - - //load preview? - const showPreview = isVisible => { - store.update(state => { - state.showPreview = isVisible - return state - }) - } - - const setSelectedComponentContext = context => { - store.update(state => { - state.selectedComponentContext = context - return state - }) - } - - const requestComponentContext = () => { - sendEvent("request-context") - } - - return { - subscribe: store.subscribe, - setDevice, - sendEvent, //may not be required - registerEventHandler, - startDrag, - stopDrag, - showPreview, - setSelectedComponentContext, - requestComponentContext, - } -} - -export const previewStore = createPreviewStore() diff --git a/packages/builder/src/stores/builder/preview.ts b/packages/builder/src/stores/builder/preview.ts new file mode 100644 index 0000000000..fe14c02535 --- /dev/null +++ b/packages/builder/src/stores/builder/preview.ts @@ -0,0 +1,90 @@ +import { get } from "svelte/store" +import { BudiStore } from "../BudiStore" + +type PreviewDevice = "desktop" | "tablet" | "mobile" +type PreviewEventHandler = (name: string, payload?: any) => void +type ComponentContext = Record + +interface PreviewState { + previewDevice: PreviewDevice + previewEventHandler: PreviewEventHandler | null + showPreview: boolean + selectedComponentContext: ComponentContext | null +} + +const INITIAL_PREVIEW_STATE: PreviewState = { + previewDevice: "desktop", + previewEventHandler: null, + showPreview: false, + selectedComponentContext: null, +} + +export class PreviewStore extends BudiStore { + constructor() { + super(INITIAL_PREVIEW_STATE) + + this.setDevice = this.setDevice.bind(this) + this.sendEvent = this.sendEvent.bind(this) + this.registerEventHandler = this.registerEventHandler.bind(this) + this.startDrag = this.startDrag.bind(this) + this.stopDrag = this.stopDrag.bind(this) + this.showPreview = this.showPreview.bind(this) + this.setSelectedComponentContext = + this.setSelectedComponentContext.bind(this) + this.requestComponentContext = this.requestComponentContext.bind(this) + } + + setDevice(device: PreviewDevice) { + this.update(state => ({ + ...state, + previewDevice: device, + })) + } + + // Potential evt names "eject-block", "dragging-new-component" + sendEvent(name: string, payload?: any) { + const { previewEventHandler } = get(this.store) + previewEventHandler?.(name, payload) + } + + registerEventHandler(handler: PreviewEventHandler) { + this.update(state => ({ + ...state, + previewEventHandler: handler, + })) + } + + startDrag(component: any) { + this.sendEvent("dragging-new-component", { + dragging: true, + component, + }) + } + + stopDrag() { + this.sendEvent("dragging-new-component", { + dragging: false, + }) + } + + //load preview? + showPreview(isVisible: boolean) { + this.update(state => ({ + ...state, + showPreview: isVisible, + })) + } + + setSelectedComponentContext(context: ComponentContext) { + this.update(state => ({ + ...state, + selectedComponentContext: context, + })) + } + + requestComponentContext() { + this.sendEvent("request-context") + } +} + +export const previewStore = new PreviewStore() From 7c36d8dac56a64f7b612f99af016f862d346daac Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 11:04:30 +0000 Subject: [PATCH 14/57] convert selectedLayout derived store --- .../builder/src/stores/builder/layouts.ts | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/stores/builder/layouts.ts b/packages/builder/src/stores/builder/layouts.ts index 0fd8efc8c0..41e61e3611 100644 --- a/packages/builder/src/stores/builder/layouts.ts +++ b/packages/builder/src/stores/builder/layouts.ts @@ -1,7 +1,7 @@ import { derived, get } from "svelte/store" import { componentStore } from "@/stores/builder" import { API } from "@/api" -import { BudiStore } from "../BudiStore" +import { BudiStore, DerivedBudiStore } from "../BudiStore" import { Layout } from "@budibase/types" interface LayoutState { @@ -9,6 +9,10 @@ interface LayoutState { selectedLayoutId: string | null } +interface DerivedLayoutState extends LayoutState { + selectedLayout: Layout | null +} + export const INITIAL_LAYOUT_STATE: LayoutState = { layouts: [], selectedLayoutId: null, @@ -62,10 +66,10 @@ export class LayoutStore extends BudiStore { } async deleteLayout(layout: Layout) { - if (!layout?._id) { + if (!layout?._id || !layout?._rev) { return } - await API.deleteLayout(layout._id, layout._rev!) + await API.deleteLayout(layout._id, layout._rev) this.update(state => { state.layouts = state.layouts.filter(x => x._id !== layout._id) return state @@ -75,6 +79,24 @@ export class LayoutStore extends BudiStore { export const layoutStore = new LayoutStore() -export const selectedLayout = derived(layoutStore, $store => { - return $store.layouts?.find(layout => layout._id === $store.selectedLayoutId) -}) +export class SelectedLayoutStore extends DerivedBudiStore< + LayoutState, + DerivedLayoutState +> { + constructor(layoutStore: LayoutStore) { + const makeDerivedStore = () => { + return derived(layoutStore, $store => { + return { + ...$store, + selectedLayout: + $store.layouts?.find( + layout => layout._id === $store.selectedLayoutId + ) || null, + } + }) + } + super(INITIAL_LAYOUT_STATE, makeDerivedStore) + } +} + +export const selectedLayout = new SelectedLayoutStore(layoutStore) From 11e55bfbd72d653adea51e3ba3ed4026b0922c5f Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 11:19:20 +0000 Subject: [PATCH 15/57] move types --- packages/builder/src/stores/builder/preview.ts | 2 +- packages/types/src/ui/stores/index.ts | 1 + packages/types/src/ui/stores/preview.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 packages/types/src/ui/stores/preview.ts diff --git a/packages/builder/src/stores/builder/preview.ts b/packages/builder/src/stores/builder/preview.ts index fe14c02535..0ec2811e15 100644 --- a/packages/builder/src/stores/builder/preview.ts +++ b/packages/builder/src/stores/builder/preview.ts @@ -1,7 +1,7 @@ import { get } from "svelte/store" import { BudiStore } from "../BudiStore" +import { PreviewDevice } from "@budibase/types" -type PreviewDevice = "desktop" | "tablet" | "mobile" type PreviewEventHandler = (name: string, payload?: any) => void type ComponentContext = Record diff --git a/packages/types/src/ui/stores/index.ts b/packages/types/src/ui/stores/index.ts index 8dae68862e..1b82a06388 100644 --- a/packages/types/src/ui/stores/index.ts +++ b/packages/types/src/ui/stores/index.ts @@ -1,3 +1,4 @@ export * from "./integration" export * from "./automations" export * from "./grid" +export * from "./preview" diff --git a/packages/types/src/ui/stores/preview.ts b/packages/types/src/ui/stores/preview.ts new file mode 100644 index 0000000000..4d09366ff5 --- /dev/null +++ b/packages/types/src/ui/stores/preview.ts @@ -0,0 +1 @@ +export type PreviewDevice = "desktop" | "tablet" | "mobile" From 2f1b7811c3eebb265f3717be94350106fff37277 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 11:25:22 +0000 Subject: [PATCH 16/57] unused import --- packages/builder/src/stores/builder/flags.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/stores/builder/flags.ts b/packages/builder/src/stores/builder/flags.ts index cff3ac4d12..6d2150f49b 100644 --- a/packages/builder/src/stores/builder/flags.ts +++ b/packages/builder/src/stores/builder/flags.ts @@ -1,4 +1,3 @@ -import { get } from "svelte/store" import { API } from "@/api" import { GetUserFlagsResponse } from "@budibase/types" import { BudiStore } from "../BudiStore" From 4ee99f807c47ff442cccfddac2d784a8bccd85cb Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 12:22:46 +0000 Subject: [PATCH 17/57] revert derivedstore implementation --- packages/builder/src/stores/builder/flags.ts | 1 + .../builder/src/stores/builder/layouts.ts | 30 +++---------------- .../builder/src/stores/builder/preview.ts | 2 +- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/packages/builder/src/stores/builder/flags.ts b/packages/builder/src/stores/builder/flags.ts index 6d2150f49b..cff3ac4d12 100644 --- a/packages/builder/src/stores/builder/flags.ts +++ b/packages/builder/src/stores/builder/flags.ts @@ -1,3 +1,4 @@ +import { get } from "svelte/store" import { API } from "@/api" import { GetUserFlagsResponse } from "@budibase/types" import { BudiStore } from "../BudiStore" diff --git a/packages/builder/src/stores/builder/layouts.ts b/packages/builder/src/stores/builder/layouts.ts index 41e61e3611..af7b17fcc7 100644 --- a/packages/builder/src/stores/builder/layouts.ts +++ b/packages/builder/src/stores/builder/layouts.ts @@ -1,7 +1,7 @@ import { derived, get } from "svelte/store" import { componentStore } from "@/stores/builder" import { API } from "@/api" -import { BudiStore, DerivedBudiStore } from "../BudiStore" +import { BudiStore } from "../BudiStore" import { Layout } from "@budibase/types" interface LayoutState { @@ -9,10 +9,6 @@ interface LayoutState { selectedLayoutId: string | null } -interface DerivedLayoutState extends LayoutState { - selectedLayout: Layout | null -} - export const INITIAL_LAYOUT_STATE: LayoutState = { layouts: [], selectedLayoutId: null, @@ -79,24 +75,6 @@ export class LayoutStore extends BudiStore { export const layoutStore = new LayoutStore() -export class SelectedLayoutStore extends DerivedBudiStore< - LayoutState, - DerivedLayoutState -> { - constructor(layoutStore: LayoutStore) { - const makeDerivedStore = () => { - return derived(layoutStore, $store => { - return { - ...$store, - selectedLayout: - $store.layouts?.find( - layout => layout._id === $store.selectedLayoutId - ) || null, - } - }) - } - super(INITIAL_LAYOUT_STATE, makeDerivedStore) - } -} - -export const selectedLayout = new SelectedLayoutStore(layoutStore) +export const selectedLayout = derived(layoutStore, $store => { + return $store.layouts?.find(layout => layout._id === $store.selectedLayoutId) +}) diff --git a/packages/builder/src/stores/builder/preview.ts b/packages/builder/src/stores/builder/preview.ts index 0ec2811e15..fe14c02535 100644 --- a/packages/builder/src/stores/builder/preview.ts +++ b/packages/builder/src/stores/builder/preview.ts @@ -1,7 +1,7 @@ import { get } from "svelte/store" import { BudiStore } from "../BudiStore" -import { PreviewDevice } from "@budibase/types" +type PreviewDevice = "desktop" | "tablet" | "mobile" type PreviewEventHandler = (name: string, payload?: any) => void type ComponentContext = Record From 6d95076d28373dbfe5a79a36a7ba5940771647fd Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 2 Jan 2025 12:59:25 +0000 Subject: [PATCH 18/57] lint --- packages/builder/src/stores/builder/flags.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/stores/builder/flags.ts b/packages/builder/src/stores/builder/flags.ts index cff3ac4d12..6d2150f49b 100644 --- a/packages/builder/src/stores/builder/flags.ts +++ b/packages/builder/src/stores/builder/flags.ts @@ -1,4 +1,3 @@ -import { get } from "svelte/store" import { API } from "@/api" import { GetUserFlagsResponse } from "@budibase/types" import { BudiStore } from "../BudiStore" From 4353e56200aaafc9bd8c1396faef4256145d1f1a Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 2 Jan 2025 14:00:24 +0000 Subject: [PATCH 19/57] Bump version to 3.2.30 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 5e0bc09825..000f9eda16 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.29", + "version": "3.2.30", "npmClient": "yarn", "concurrency": 20, "command": { From 46a132a220fe585214a1ca1ecdf8dfdc82ea337e Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 2 Jan 2025 14:31:42 +0000 Subject: [PATCH 20/57] Bump version to 3.2.31 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 000f9eda16..155f4f5ba3 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.30", + "version": "3.2.31", "npmClient": "yarn", "concurrency": 20, "command": { From aba5fbfd89b9b6b6ebc3c5274add460470a9a5cd Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 2 Jan 2025 16:04:17 +0100 Subject: [PATCH 21/57] Fix user cell search --- .../src/components/grid/cells/BBReferenceCell.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/cells/BBReferenceCell.svelte b/packages/frontend-core/src/components/grid/cells/BBReferenceCell.svelte index 5d98ba903b..fe6d8945ba 100644 --- a/packages/frontend-core/src/components/grid/cells/BBReferenceCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/BBReferenceCell.svelte @@ -26,7 +26,7 @@ : RelationshipType.MANY_TO_MANY, } - async function searchFunction(searchParams) { + async function searchFunction(_tableId, searchParams) { if ( subtype !== BBReferenceFieldSubType.USER && subtype !== BBReferenceFieldSubType.USERS From 94adbb15adc43dc2fa8b71ad5ca18f326a598e96 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 2 Jan 2025 15:17:22 +0000 Subject: [PATCH 22/57] Bump version to 3.2.32 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 155f4f5ba3..dde9cf03a0 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.31", + "version": "3.2.32", "npmClient": "yarn", "concurrency": 20, "command": { From b4b805ac1c94cfc5594f1e50a695a5441acb55f3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 3 Jan 2025 11:02:09 +0100 Subject: [PATCH 23/57] Fix queries when returning nulls --- packages/server/src/threads/query.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index facdd20642..3ba4995b2c 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -174,7 +174,9 @@ class QueryRunner { } // needs to an array for next step - if (!Array.isArray(rows)) { + if (rows === null) { + rows = [] + } else if (!Array.isArray(rows)) { rows = [rows] } From 9c7beeeeaf846dfdb71f942ed686d1bbe0e199ea Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 3 Jan 2025 10:42:59 +0000 Subject: [PATCH 24/57] user and websocket stores converted to typescript --- packages/builder/src/stores/builder/users.js | 62 --------- packages/builder/src/stores/builder/users.ts | 72 ++++++++++ .../builder/src/stores/builder/websocket.js | 95 -------------- .../builder/src/stores/builder/websocket.ts | 124 ++++++++++++++++++ .../src/utils/{websocket.js => websocket.ts} | 16 ++- packages/types/src/ui/stores/grid/user.ts | 1 + 6 files changed, 208 insertions(+), 162 deletions(-) delete mode 100644 packages/builder/src/stores/builder/users.js create mode 100644 packages/builder/src/stores/builder/users.ts delete mode 100644 packages/builder/src/stores/builder/websocket.js create mode 100644 packages/builder/src/stores/builder/websocket.ts rename packages/frontend-core/src/utils/{websocket.js => websocket.ts} (78%) diff --git a/packages/builder/src/stores/builder/users.js b/packages/builder/src/stores/builder/users.js deleted file mode 100644 index 0794c63289..0000000000 --- a/packages/builder/src/stores/builder/users.js +++ /dev/null @@ -1,62 +0,0 @@ -import { writable, get, derived } from "svelte/store" - -export const createUserStore = () => { - const store = writable([]) - - const init = users => { - store.set(users) - } - - const updateUser = user => { - const $users = get(store) - if (!$users.some(x => x.sessionId === user.sessionId)) { - store.set([...$users, user]) - } else { - store.update(state => { - const index = state.findIndex(x => x.sessionId === user.sessionId) - state[index] = user - return state.slice() - }) - } - } - - const removeUser = sessionId => { - store.update(state => { - return state.filter(x => x.sessionId !== sessionId) - }) - } - - const reset = () => { - store.set([]) - } - - return { - ...store, - actions: { - init, - updateUser, - removeUser, - reset, - }, - } -} - -export const userStore = createUserStore() - -export const userSelectedResourceMap = derived(userStore, $userStore => { - let map = {} - $userStore.forEach(user => { - const resource = user.builderMetadata?.selectedResourceId - if (resource) { - if (!map[resource]) { - map[resource] = [] - } - map[resource].push(user) - } - }) - return map -}) - -export const isOnlyUser = derived(userStore, $userStore => { - return $userStore.length < 2 -}) diff --git a/packages/builder/src/stores/builder/users.ts b/packages/builder/src/stores/builder/users.ts new file mode 100644 index 0000000000..5f0c4a3701 --- /dev/null +++ b/packages/builder/src/stores/builder/users.ts @@ -0,0 +1,72 @@ +import { get, derived } from "svelte/store" +import { BudiStore } from "../BudiStore" +import { UIUser } from "@budibase/types" + +export class UserStore extends BudiStore { + actions: { + init: (users: UIUser[]) => void + updateUser: (user: UIUser) => void + removeUser: (sessionId: string) => void + reset: () => void + } + + constructor() { + super([]) + this.actions = { + init: this.init.bind(this), + updateUser: this.updateUser.bind(this), + removeUser: this.removeUser.bind(this), + reset: this.reset.bind(this), + } + } + + init(users: UIUser[]) { + this.store.set(users) + } + + updateUser(user: UIUser) { + const $users = get(this.store) + if (!$users.some(x => x.sessionId === user.sessionId)) { + this.store.set([...$users, user]) + } else { + this.update(state => { + const index = state.findIndex(x => x.sessionId === user.sessionId) + state[index] = user + return state.slice() + }) + } + } + + removeUser(sessionId: string) { + this.update(state => { + return state.filter(x => x.sessionId !== sessionId) + }) + } + + reset() { + this.store.set([]) + } +} + +export const userStore = new UserStore() + +export const userSelectedResourceMap = derived( + userStore, + ($userStore): Record => { + let map: Record = {} + $userStore.forEach(user => { + const resource = user.builderMetadata?.selectedResourceId + if (resource) { + if (!map[resource]) { + map[resource] = [] + } + map[resource].push(user) + } + }) + return map + } +) + +export const isOnlyUser = derived(userStore, $userStore => { + return $userStore.length < 2 +}) diff --git a/packages/builder/src/stores/builder/websocket.js b/packages/builder/src/stores/builder/websocket.js deleted file mode 100644 index 3944c8cba5..0000000000 --- a/packages/builder/src/stores/builder/websocket.js +++ /dev/null @@ -1,95 +0,0 @@ -import { createWebsocket } from "@budibase/frontend-core" -import { - automationStore, - userStore, - appStore, - themeStore, - navigationStore, - deploymentStore, - snippets, - datasources, - tables, - roles, -} from "@/stores/builder" -import { get } from "svelte/store" -import { auth, appsStore } from "@/stores/portal" -import { screenStore } from "./screens" -import { SocketEvent, BuilderSocketEvent, helpers } from "@budibase/shared-core" -import { notifications } from "@budibase/bbui" - -export const createBuilderWebsocket = appId => { - const socket = createWebsocket("/socket/builder") - - // Built-in events - socket.on("connect", () => { - socket.emit(BuilderSocketEvent.SelectApp, { appId }, ({ users }) => { - userStore.actions.init(users) - }) - }) - socket.on("connect_error", err => { - console.error("Failed to connect to builder websocket:", err.message) - }) - socket.on("disconnect", () => { - userStore.actions.reset() - }) - - // User events - socket.onOther(SocketEvent.UserUpdate, ({ user }) => { - userStore.actions.updateUser(user) - }) - socket.onOther(SocketEvent.UserDisconnect, ({ sessionId }) => { - userStore.actions.removeUser(sessionId) - }) - socket.onOther(BuilderSocketEvent.LockTransfer, ({ userId }) => { - if (userId === get(auth)?.user?._id) { - appStore.update(state => ({ - ...state, - hasLock: true, - })) - } - }) - - // Data section events - socket.onOther(BuilderSocketEvent.TableChange, ({ id, table }) => { - tables.replaceTable(id, table) - }) - socket.onOther(BuilderSocketEvent.DatasourceChange, ({ id, datasource }) => { - datasources.replaceDatasource(id, datasource) - }) - - // Role events - socket.onOther(BuilderSocketEvent.RoleChange, ({ id, role }) => { - roles.replace(id, role) - }) - - // Design section events - socket.onOther(BuilderSocketEvent.ScreenChange, ({ id, screen }) => { - screenStore.replace(id, screen) - }) - - // App events - socket.onOther(BuilderSocketEvent.AppMetadataChange, ({ metadata }) => { - appStore.syncMetadata(metadata) - themeStore.syncMetadata(metadata) - navigationStore.syncMetadata(metadata) - snippets.syncMetadata(metadata) - }) - socket.onOther( - BuilderSocketEvent.AppPublishChange, - async ({ user, published }) => { - await appsStore.load() - if (published) { - await deploymentStore.load() - } - const verb = published ? "published" : "unpublished" - notifications.success(`${helpers.getUserLabel(user)} ${verb} this app`) - } - ) - - // Automation events - socket.onOther(BuilderSocketEvent.AutomationChange, ({ id, automation }) => { - automationStore.actions.replace(id, automation) - }) - - return socket -} diff --git a/packages/builder/src/stores/builder/websocket.ts b/packages/builder/src/stores/builder/websocket.ts new file mode 100644 index 0000000000..49b8067dd8 --- /dev/null +++ b/packages/builder/src/stores/builder/websocket.ts @@ -0,0 +1,124 @@ +import { createWebsocket } from "@budibase/frontend-core" +import { + automationStore, + userStore, + appStore, + themeStore, + navigationStore, + deploymentStore, + snippets, + datasources, + tables, + roles, +} from "@/stores/builder" +import { get } from "svelte/store" +import { auth, appsStore } from "@/stores/portal" +import { screenStore } from "./screens" +import { SocketEvent, BuilderSocketEvent, helpers } from "@budibase/shared-core" +import { notifications } from "@budibase/bbui" +import { Automation, Datasource, Role, Table, UIUser } from "@budibase/types" + +export const createBuilderWebsocket = (appId: string) => { + const socket = createWebsocket("/socket/builder") + + // Built-in events + socket.on("connect", () => { + socket.emit( + BuilderSocketEvent.SelectApp, + { appId }, + ({ users }: { users: UIUser[] }) => { + userStore.actions.init(users) + } + ) + }) + socket.on("connect_error", err => { + console.error("Failed to connect to builder websocket:", err.message) + }) + socket.on("disconnect", () => { + userStore.actions.reset() + }) + + // User events + socket.onOther(SocketEvent.UserUpdate, ({ user }: { user: UIUser }) => { + userStore.actions.updateUser(user) + }) + socket.onOther( + SocketEvent.UserDisconnect, + ({ sessionId }: { sessionId: string }) => { + userStore.actions.removeUser(sessionId) + } + ) + socket.onOther( + BuilderSocketEvent.LockTransfer, + ({ userId }: { userId: string }) => { + if (userId === get(auth)?.user?._id) { + appStore.update(state => ({ + ...state, + hasLock: true, + })) + } + } + ) + + // Data section events + socket.onOther( + BuilderSocketEvent.TableChange, + ({ id, table }: { id: string; table: Table }) => { + tables.replaceTable(id, table) + } + ) + socket.onOther( + BuilderSocketEvent.DatasourceChange, + ({ id, datasource }: { id: string; datasource: Datasource }) => { + datasources.replaceDatasource(id, datasource) + } + ) + + // Role events + socket.onOther( + BuilderSocketEvent.RoleChange, + ({ id, role }: { id: string; role: Role }) => { + roles.replace(id, role) + } + ) + + // Design section events + socket.onOther( + BuilderSocketEvent.ScreenChange, + ({ id, screen }: { id: string; screen: Screen }) => { + screenStore.replace(id, screen) + } + ) + + // App events + socket.onOther( + BuilderSocketEvent.AppMetadataChange, + ({ metadata }: { metadata: any }) => { + appStore.syncMetadata(metadata) + themeStore.syncMetadata(metadata) + navigationStore.syncMetadata(metadata) + snippets.syncMetadata(metadata) + } + ) + socket.onOther( + BuilderSocketEvent.AppPublishChange, + async ({ user, published }: { user: UIUser; published: boolean }) => { + await appsStore.load() + if (published) { + await deploymentStore.load() + } + const verb = published ? "published" : "unpublished" + notifications.success(`${helpers.getUserLabel(user)} ${verb} this app`) + } + ) + + // Automation events + socket.onOther( + BuilderSocketEvent.AutomationChange, + ({ id, automation }: { id: string; automation: Automation }) => { + automationStore.actions.replace(id, automation) + } + ) + + return socket +} diff --git a/packages/frontend-core/src/utils/websocket.js b/packages/frontend-core/src/utils/websocket.ts similarity index 78% rename from packages/frontend-core/src/utils/websocket.js rename to packages/frontend-core/src/utils/websocket.ts index dee679eaef..475b14176f 100644 --- a/packages/frontend-core/src/utils/websocket.js +++ b/packages/frontend-core/src/utils/websocket.ts @@ -1,12 +1,18 @@ -import { io } from "socket.io-client" +import { io, Socket } from "socket.io-client" import { SocketEvent, SocketSessionTTL } from "@budibase/shared-core" import { APISessionID } from "../api" const DefaultOptions = { heartbeat: true, } +export interface ExtendedSocket extends Socket { + onOther: (event: string, callback: (data: any) => void) => void +} -export const createWebsocket = (path, options = DefaultOptions) => { +export const createWebsocket = ( + path: string, + options = DefaultOptions +): ExtendedSocket => { if (!path) { throw "A websocket path must be provided" } @@ -32,10 +38,10 @@ export const createWebsocket = (path, options = DefaultOptions) => { // Disable polling and rely on websocket only, as HTTP transport // will only work with sticky sessions which we don't have transports: ["websocket"], - }) + }) as ExtendedSocket // Set up a heartbeat that's half of the session TTL - let interval + let interval: NodeJS.Timeout | undefined if (heartbeat) { interval = setInterval(() => { socket.emit(SocketEvent.Heartbeat) @@ -48,7 +54,7 @@ export const createWebsocket = (path, options = DefaultOptions) => { // Helper utility to ignore events that were triggered due to API // changes made by us - socket.onOther = (event, callback) => { + socket.onOther = (event: string, callback: (data: any) => void) => { socket.on(event, data => { if (data?.apiSessionId !== APISessionID) { callback(data) diff --git a/packages/types/src/ui/stores/grid/user.ts b/packages/types/src/ui/stores/grid/user.ts index b6eb529805..9625b0bb80 100644 --- a/packages/types/src/ui/stores/grid/user.ts +++ b/packages/types/src/ui/stores/grid/user.ts @@ -3,4 +3,5 @@ import { User } from "@budibase/types" export interface UIUser extends User { sessionId: string gridMetadata?: { focusedCellId?: string } + builderMetadata?: { selectedResourceId?: string } } From 8a4f42003c8702841ebc15a28884ec39b77abd04 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 3 Jan 2025 11:31:48 +0000 Subject: [PATCH 25/57] flatten actions --- packages/builder/src/stores/builder/users.ts | 21 ++++--------------- .../builder/src/stores/builder/websocket.ts | 8 +++---- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/packages/builder/src/stores/builder/users.ts b/packages/builder/src/stores/builder/users.ts index 5f0c4a3701..5350b2af90 100644 --- a/packages/builder/src/stores/builder/users.ts +++ b/packages/builder/src/stores/builder/users.ts @@ -3,31 +3,18 @@ import { BudiStore } from "../BudiStore" import { UIUser } from "@budibase/types" export class UserStore extends BudiStore { - actions: { - init: (users: UIUser[]) => void - updateUser: (user: UIUser) => void - removeUser: (sessionId: string) => void - reset: () => void - } - constructor() { super([]) - this.actions = { - init: this.init.bind(this), - updateUser: this.updateUser.bind(this), - removeUser: this.removeUser.bind(this), - reset: this.reset.bind(this), - } } init(users: UIUser[]) { - this.store.set(users) + this.set(users) } updateUser(user: UIUser) { - const $users = get(this.store) + const $users = get(this) if (!$users.some(x => x.sessionId === user.sessionId)) { - this.store.set([...$users, user]) + this.set([...$users, user]) } else { this.update(state => { const index = state.findIndex(x => x.sessionId === user.sessionId) @@ -44,7 +31,7 @@ export class UserStore extends BudiStore { } reset() { - this.store.set([]) + this.set([]) } } diff --git a/packages/builder/src/stores/builder/websocket.ts b/packages/builder/src/stores/builder/websocket.ts index 49b8067dd8..bd9e2c8d4d 100644 --- a/packages/builder/src/stores/builder/websocket.ts +++ b/packages/builder/src/stores/builder/websocket.ts @@ -27,7 +27,7 @@ export const createBuilderWebsocket = (appId: string) => { BuilderSocketEvent.SelectApp, { appId }, ({ users }: { users: UIUser[] }) => { - userStore.actions.init(users) + userStore.init(users) } ) }) @@ -35,17 +35,17 @@ export const createBuilderWebsocket = (appId: string) => { console.error("Failed to connect to builder websocket:", err.message) }) socket.on("disconnect", () => { - userStore.actions.reset() + userStore.reset() }) // User events socket.onOther(SocketEvent.UserUpdate, ({ user }: { user: UIUser }) => { - userStore.actions.updateUser(user) + userStore.updateUser(user) }) socket.onOther( SocketEvent.UserDisconnect, ({ sessionId }: { sessionId: string }) => { - userStore.actions.removeUser(sessionId) + userStore.removeUser(sessionId) } ) socket.onOther( From 428df339c4b0a6c4933fcd4221879031529a50f3 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 3 Jan 2025 16:33:51 +0000 Subject: [PATCH 26/57] Theme / Row actions / Snippers stores --- .../builder/{rowActions.js => rowActions.ts} | 57 +++++++++------- .../builder/src/stores/builder/snippets.js | 35 ---------- .../builder/src/stores/builder/snippets.ts | 32 +++++++++ packages/builder/src/stores/builder/theme.js | 58 ---------------- packages/builder/src/stores/builder/theme.ts | 67 +++++++++++++++++++ 5 files changed, 132 insertions(+), 117 deletions(-) rename packages/builder/src/stores/builder/{rowActions.js => rowActions.ts} (71%) delete mode 100644 packages/builder/src/stores/builder/snippets.js create mode 100644 packages/builder/src/stores/builder/snippets.ts delete mode 100644 packages/builder/src/stores/builder/theme.js create mode 100644 packages/builder/src/stores/builder/theme.ts diff --git a/packages/builder/src/stores/builder/rowActions.js b/packages/builder/src/stores/builder/rowActions.ts similarity index 71% rename from packages/builder/src/stores/builder/rowActions.js rename to packages/builder/src/stores/builder/rowActions.ts index 9cc4063b91..378579e41b 100644 --- a/packages/builder/src/stores/builder/rowActions.js +++ b/packages/builder/src/stores/builder/rowActions.ts @@ -6,18 +6,29 @@ import { automationStore } from "./automations" import { API } from "@/api" import { getSequentialName } from "@/helpers/duplicate" -const initialState = {} +interface RowAction { + id: string + name: string + tableId: string + allowedSources?: string[] +} -export class RowActionStore extends BudiStore { +interface RowActionState { + [tableId: string]: RowAction[] +} + +const initialState: RowActionState = {} + +export class RowActionStore extends BudiStore { constructor() { super(initialState) } reset = () => { - this.store.set(initialState) + this.set(initialState) } - refreshRowActions = async sourceId => { + refreshRowActions = async (sourceId: string) => { if (!sourceId) { return } @@ -34,26 +45,30 @@ export class RowActionStore extends BudiStore { // Fetch row actions for this table const res = await API.rowActions.fetch(tableId) - const actions = Object.values(res || {}) + const actions = Object.values(res || {}) as RowAction[] this.update(state => ({ ...state, [tableId]: actions, })) } - createRowAction = async (tableId, viewId, name) => { + createRowAction = async (tableId: string, viewId?: string, name?: string) => { if (!tableId) { return } // Get a unique name for this action if (!name) { - const existingRowActions = get(this.store)[tableId] || [] + const existingRowActions = get(this)[tableId] || [] name = getSequentialName(existingRowActions, "New row action ", { getName: x => x.name, }) } + if (!name) { + return + } + // Create the action const res = await API.rowActions.create(tableId, name) @@ -73,41 +88,35 @@ export class RowActionStore extends BudiStore { return res } - enableView = async (tableId, rowActionId, viewId) => { + enableView = async (tableId: string, rowActionId: string, viewId: string) => { await API.rowActions.enableView(tableId, rowActionId, viewId) await this.refreshRowActions(tableId) } - disableView = async (tableId, rowActionId, viewId) => { + disableView = async ( + tableId: string, + rowActionId: string, + viewId: string + ) => { await API.rowActions.disableView(tableId, rowActionId, viewId) await this.refreshRowActions(tableId) } - rename = async (tableId, rowActionId, name) => { - await API.rowActions.update({ - tableId, - rowActionId, - name, - }) - await this.refreshRowActions(tableId) - automationStore.actions.fetch() - } - - delete = async (tableId, rowActionId) => { + delete = async (tableId: string, rowActionId: string) => { await API.rowActions.delete(tableId, rowActionId) await this.refreshRowActions(tableId) // We don't need to refresh automations as we can only delete row actions // from the automations store, so we already handle the state update there } - trigger = async (sourceId, rowActionId, rowId) => { + trigger = async (sourceId: string, rowActionId: string, rowId: string) => { await API.rowActions.trigger(sourceId, rowActionId, rowId) } } const store = new RowActionStore() -const derivedStore = derived(store, $store => { - let map = {} +const derivedStore = derived(store, $store => { + const map: RowActionState = {} // Generate an entry for every view as well Object.keys($store || {}).forEach(tableId => { @@ -115,7 +124,7 @@ const derivedStore = derived(store, $store => { map[tableId] = $store[tableId] for (let action of $store[tableId]) { const otherSources = (action.allowedSources || []).filter( - sourceId => sourceId !== tableId + (sourceId: string) => sourceId !== tableId ) for (let source of otherSources) { map[source] ??= [] diff --git a/packages/builder/src/stores/builder/snippets.js b/packages/builder/src/stores/builder/snippets.js deleted file mode 100644 index 4e98ef1bdc..0000000000 --- a/packages/builder/src/stores/builder/snippets.js +++ /dev/null @@ -1,35 +0,0 @@ -import { writable, get } from "svelte/store" -import { API } from "@/api" -import { appStore } from "./app" - -const createsnippets = () => { - const store = writable([]) - - const syncMetadata = metadata => { - store.set(metadata?.snippets || []) - } - - const saveSnippet = async updatedSnippet => { - const snippets = [ - ...get(store).filter(snippet => snippet.name !== updatedSnippet.name), - updatedSnippet, - ] - const app = await API.saveAppMetadata(get(appStore).appId, { snippets }) - syncMetadata(app) - } - - const deleteSnippet = async snippetName => { - const snippets = get(store).filter(snippet => snippet.name !== snippetName) - const app = await API.saveAppMetadata(get(appStore).appId, { snippets }) - syncMetadata(app) - } - - return { - ...store, - syncMetadata, - saveSnippet, - deleteSnippet, - } -} - -export const snippets = createsnippets() diff --git a/packages/builder/src/stores/builder/snippets.ts b/packages/builder/src/stores/builder/snippets.ts new file mode 100644 index 0000000000..a6a63f7c89 --- /dev/null +++ b/packages/builder/src/stores/builder/snippets.ts @@ -0,0 +1,32 @@ +import { get } from "svelte/store" +import { API } from "@/api" +import { appStore } from "./app" +import { BudiStore } from "../BudiStore" +import { Snippet, UpdateAppResponse } from "@budibase/types" + +export class SnippetStore extends BudiStore { + constructor() { + super([]) + } + + syncMetadata = (metadata: UpdateAppResponse) => { + this.set(metadata?.snippets || []) + } + + saveSnippet = async (updatedSnippet: Snippet) => { + const snippets = [ + ...get(this).filter(snippet => snippet.name !== updatedSnippet.name), + updatedSnippet, + ] + const app = await API.saveAppMetadata(get(appStore).appId, { snippets }) + this.syncMetadata(app) + } + + deleteSnippet = async (snippetName: string) => { + const snippets = get(this).filter(snippet => snippet.name !== snippetName) + const app = await API.saveAppMetadata(get(appStore).appId, { snippets }) + this.syncMetadata(app) + } +} + +export const snippets = new SnippetStore() diff --git a/packages/builder/src/stores/builder/theme.js b/packages/builder/src/stores/builder/theme.js deleted file mode 100644 index ed46e9095a..0000000000 --- a/packages/builder/src/stores/builder/theme.js +++ /dev/null @@ -1,58 +0,0 @@ -import { writable, get } from "svelte/store" -import { API } from "@/api" -import { ensureValidTheme, DefaultAppTheme } from "@budibase/shared-core" - -export const createThemeStore = () => { - const store = writable({ - theme: DefaultAppTheme, - customTheme: {}, - }) - - const syncAppTheme = app => { - store.update(state => { - const theme = ensureValidTheme(app.theme, DefaultAppTheme) - return { - ...state, - theme, - customTheme: app.customTheme, - } - }) - } - - const save = async (theme, appId) => { - const app = await API.saveAppMetadata(appId, { theme }) - store.update(state => { - state.theme = app.theme - return state - }) - } - - const saveCustom = async (theme, appId) => { - const updated = { ...get(store).customTheme, ...theme } - const app = await API.saveAppMetadata(appId, { customTheme: updated }) - store.update(state => { - state.customTheme = app.customTheme - return state - }) - } - - const syncMetadata = metadata => { - const { theme, customTheme } = metadata - store.update(state => ({ - ...state, - theme: ensureValidTheme(theme, DefaultAppTheme), - customTheme, - })) - } - - return { - subscribe: store.subscribe, - update: store.update, - syncMetadata, - syncAppTheme, - save, - saveCustom, - } -} - -export const themeStore = createThemeStore() diff --git a/packages/builder/src/stores/builder/theme.ts b/packages/builder/src/stores/builder/theme.ts new file mode 100644 index 0000000000..b3ac202a5d --- /dev/null +++ b/packages/builder/src/stores/builder/theme.ts @@ -0,0 +1,67 @@ +import { get } from "svelte/store" +import { API } from "@/api" +import { BudiStore } from "../BudiStore" +import { ensureValidTheme, DefaultAppTheme } from "@budibase/shared-core" +import { App, UpdateAppResponse, Theme, AppCustomTheme } from "@budibase/types" + +interface ThemeState { + theme: Theme + customTheme: AppCustomTheme +} + +export class ThemeStore extends BudiStore { + constructor() { + super({ + theme: DefaultAppTheme as Theme, + customTheme: {}, + }) + } + + syncAppTheme = (app: App) => { + this.update(state => { + const theme = ensureValidTheme( + app.theme as Theme | undefined, + DefaultAppTheme + ) as Theme + return { + ...state, + theme, + customTheme: app.customTheme || {}, + } + }) + } + + save = async (theme: Theme, appId: string) => { + const app = await API.saveAppMetadata(appId, { theme }) + this.update(state => ({ + ...state, + theme: ensureValidTheme( + app.theme as Theme | undefined, + DefaultAppTheme + ) as Theme, + })) + } + + saveCustom = async (theme: Partial, appId: string) => { + const updated = { ...get(this).customTheme, ...theme } + const app = await API.saveAppMetadata(appId, { customTheme: updated }) + this.update(state => ({ + ...state, + customTheme: app.customTheme || {}, + })) + } + + syncMetadata = (metadata: UpdateAppResponse) => { + const { theme, customTheme } = metadata + this.update(state => ({ + ...state, + theme: ensureValidTheme( + theme as Theme | undefined, + DefaultAppTheme + ) as Theme, + customTheme: customTheme || {}, + })) + } +} + +export const themeStore = new ThemeStore() From 47c87a6650ef5b25b07d3be9b0d5d91ccfcfdcd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 02:27:34 +0000 Subject: [PATCH 27/57] Bump next from 14.2.15 to 14.2.21 in /examples/nextjs-api-sales Bumps [next](https://github.com/vercel/next.js) from 14.2.15 to 14.2.21. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v14.2.15...v14.2.21) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- examples/nextjs-api-sales/package.json | 2 +- examples/nextjs-api-sales/yarn.lock | 108 ++++++++++++------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/examples/nextjs-api-sales/package.json b/examples/nextjs-api-sales/package.json index 1050c6b75e..d50e7d4eb5 100644 --- a/examples/nextjs-api-sales/package.json +++ b/examples/nextjs-api-sales/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "bulma": "^0.9.3", - "next": "14.2.15", + "next": "14.2.21", "node-fetch": "^3.2.10", "sass": "^1.52.3", "react": "17.0.2", diff --git a/examples/nextjs-api-sales/yarn.lock b/examples/nextjs-api-sales/yarn.lock index b595a148bf..a10fccb2e9 100644 --- a/examples/nextjs-api-sales/yarn.lock +++ b/examples/nextjs-api-sales/yarn.lock @@ -46,10 +46,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@next/env@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.15.tgz#06d984e37e670d93ddd6790af1844aeb935f332f" - integrity sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ== +"@next/env@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.21.tgz#09ff0813d29c596397e141205d4f5fd5c236bdd0" + integrity sha512-lXcwcJd5oR01tggjWJ6SrNNYFGuOOMB9c251wUNkjCpkoXOPkDeF/15c3mnVlBqrW4JJXb2kVxDFhC4GduJt2A== "@next/eslint-plugin-next@12.1.0": version "12.1.0" @@ -58,50 +58,50 @@ dependencies: glob "7.1.7" -"@next/swc-darwin-arm64@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz#6386d585f39a1c490c60b72b1f76612ba4434347" - integrity sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA== +"@next/swc-darwin-arm64@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.21.tgz#32a31992aace1440981df9cf7cb3af7845d94fec" + integrity sha512-HwEjcKsXtvszXz5q5Z7wCtrHeTTDSTgAbocz45PHMUjU3fBYInfvhR+ZhavDRUYLonm53aHZbB09QtJVJj8T7g== -"@next/swc-darwin-x64@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz#b7baeedc6a28f7545ad2bc55adbab25f7b45cb89" - integrity sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg== +"@next/swc-darwin-x64@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.21.tgz#5ab4b3f6685b6b52f810d0f5cf6e471480ddffdb" + integrity sha512-TSAA2ROgNzm4FhKbTbyJOBrsREOMVdDIltZ6aZiKvCi/v0UwFmwigBGeqXDA97TFMpR3LNNpw52CbVelkoQBxA== -"@next/swc-linux-arm64-gnu@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz#fa13c59d3222f70fb4cb3544ac750db2c6e34d02" - integrity sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw== +"@next/swc-linux-arm64-gnu@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.21.tgz#8a0e1fa887aef19ca218af2af515d0a5ee67ba3f" + integrity sha512-0Dqjn0pEUz3JG+AImpnMMW/m8hRtl1GQCNbO66V1yp6RswSTiKmnHf3pTX6xMdJYSemf3O4Q9ykiL0jymu0TuA== -"@next/swc-linux-arm64-musl@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz#30e45b71831d9a6d6d18d7ac7d611a8d646a17f9" - integrity sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ== +"@next/swc-linux-arm64-musl@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.21.tgz#ddad844406b42fa8965fe11250abc85c1fe0fd05" + integrity sha512-Ggfw5qnMXldscVntwnjfaQs5GbBbjioV4B4loP+bjqNEb42fzZlAaK+ldL0jm2CTJga9LynBMhekNfV8W4+HBw== -"@next/swc-linux-x64-gnu@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz#5065db17fc86f935ad117483f21f812dc1b39254" - integrity sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA== +"@next/swc-linux-x64-gnu@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.21.tgz#db55fd666f9ba27718f65caa54b622a912cdd16b" + integrity sha512-uokj0lubN1WoSa5KKdThVPRffGyiWlm/vCc/cMkWOQHw69Qt0X1o3b2PyLLx8ANqlefILZh1EdfLRz9gVpG6tg== -"@next/swc-linux-x64-musl@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz#3c4a4568d8be7373a820f7576cf33388b5dab47e" - integrity sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ== +"@next/swc-linux-x64-musl@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.21.tgz#dddb850353624efcd58c4c4e30ad8a1aab379642" + integrity sha512-iAEBPzWNbciah4+0yI4s7Pce6BIoxTQ0AGCkxn/UBuzJFkYyJt71MadYQkjPqCQCJAFQ26sYh7MOKdU+VQFgPg== -"@next/swc-win32-arm64-msvc@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz#fb812cc4ca0042868e32a6a021da91943bb08b98" - integrity sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g== +"@next/swc-win32-arm64-msvc@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.21.tgz#290012ee57b196d3d2d04853e6bf0179cae9fbaf" + integrity sha512-plykgB3vL2hB4Z32W3ktsfqyuyGAPxqwiyrAi2Mr8LlEUhNn9VgkiAl5hODSBpzIfWweX3er1f5uNpGDygfQVQ== -"@next/swc-win32-ia32-msvc@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz#ec26e6169354f8ced240c1427be7fd485c5df898" - integrity sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ== +"@next/swc-win32-ia32-msvc@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.21.tgz#c959135a78cab18cca588d11d1e33bcf199590d4" + integrity sha512-w5bacz4Vxqrh06BjWgua3Yf7EMDb8iMcVhNrNx8KnJXt8t+Uu0Zg4JHLDL/T7DkTCEEfKXO/Er1fcfWxn2xfPA== -"@next/swc-win32-x64-msvc@14.2.15": - version "14.2.15" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz#18d68697002b282006771f8d92d79ade9efd35c4" - integrity sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g== +"@next/swc-win32-x64-msvc@14.2.21": + version "14.2.21" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.21.tgz#21ff892286555b90538a7d1b505ea21a005d6ead" + integrity sha512-sT6+llIkzpsexGYZq8cjjthRyRGe5cJVhqh12FmlbxHqna6zsDDK8UNaV7g41T6atFHCJUPeLb3uyAwrBwy0NA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1253,12 +1253,12 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -next@14.2.15: - version "14.2.15" - resolved "https://registry.yarnpkg.com/next/-/next-14.2.15.tgz#348e5603e22649775d19c785c09a89c9acb5189a" - integrity sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw== +next@14.2.21: + version "14.2.21" + resolved "https://registry.yarnpkg.com/next/-/next-14.2.21.tgz#f6da9e2abba1a0e4ca7a5273825daf06632554ba" + integrity sha512-rZmLwucLHr3/zfDMYbJXbw0ZeoBpirxkXuvsJbk7UPorvPYZhP7vq7aHbKnU7dQNCYIimRrbB2pp3xmf+wsYUg== dependencies: - "@next/env" "14.2.15" + "@next/env" "14.2.21" "@swc/helpers" "0.5.5" busboy "1.6.0" caniuse-lite "^1.0.30001579" @@ -1266,15 +1266,15 @@ next@14.2.15: postcss "8.4.31" styled-jsx "5.1.1" optionalDependencies: - "@next/swc-darwin-arm64" "14.2.15" - "@next/swc-darwin-x64" "14.2.15" - "@next/swc-linux-arm64-gnu" "14.2.15" - "@next/swc-linux-arm64-musl" "14.2.15" - "@next/swc-linux-x64-gnu" "14.2.15" - "@next/swc-linux-x64-musl" "14.2.15" - "@next/swc-win32-arm64-msvc" "14.2.15" - "@next/swc-win32-ia32-msvc" "14.2.15" - "@next/swc-win32-x64-msvc" "14.2.15" + "@next/swc-darwin-arm64" "14.2.21" + "@next/swc-darwin-x64" "14.2.21" + "@next/swc-linux-arm64-gnu" "14.2.21" + "@next/swc-linux-arm64-musl" "14.2.21" + "@next/swc-linux-x64-gnu" "14.2.21" + "@next/swc-linux-x64-musl" "14.2.21" + "@next/swc-win32-arm64-msvc" "14.2.21" + "@next/swc-win32-ia32-msvc" "14.2.21" + "@next/swc-win32-x64-msvc" "14.2.21" node-domexception@^1.0.0: version "1.0.0" From 4469e38ab87725b1ed09122b5dc5f890c91b06e3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 6 Jan 2025 10:27:37 +0000 Subject: [PATCH 28/57] Fix triggering automations --- packages/client/src/utils/buttonActions.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 9d0bddcc92..16dc3c97e7 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -216,11 +216,11 @@ const deleteRowHandler = async action => { const triggerAutomationHandler = async action => { const { fields, notificationOverride, timeout } = action.parameters try { - const result = await API.triggerAutomation({ - automationId: action.parameters.automationId, + const result = await API.triggerAutomation( + action.parameters.automationId, fields, - timeout, - }) + timeout + ) // Value will exist if automation is synchronous, so return it. if (result.value) { From f2440f3727a76e81f0ad534d852309b4a559aa0d Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 10:34:57 +0000 Subject: [PATCH 29/57] convert roles stores to typescript --- packages/builder/src/stores/builder/roles.js | 88 ---------------- packages/builder/src/stores/builder/roles.ts | 104 +++++++++++++++++++ 2 files changed, 104 insertions(+), 88 deletions(-) delete mode 100644 packages/builder/src/stores/builder/roles.js create mode 100644 packages/builder/src/stores/builder/roles.ts diff --git a/packages/builder/src/stores/builder/roles.js b/packages/builder/src/stores/builder/roles.js deleted file mode 100644 index e718545f14..0000000000 --- a/packages/builder/src/stores/builder/roles.js +++ /dev/null @@ -1,88 +0,0 @@ -import { derived, writable, get } from "svelte/store" -import { API } from "@/api" -import { RoleUtils } from "@budibase/frontend-core" - -export function createRolesStore() { - const store = writable([]) - const enriched = derived(store, $store => { - return $store.map(role => ({ - ...role, - - // Ensure we have new metadata for all roles - uiMetadata: { - displayName: role.uiMetadata?.displayName || role.name, - color: - role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", - description: role.uiMetadata?.description || "Custom role", - }, - })) - }) - - function setRoles(roles) { - store.set( - roles.sort((a, b) => { - const priorityA = RoleUtils.getRolePriority(a._id) - const priorityB = RoleUtils.getRolePriority(b._id) - if (priorityA !== priorityB) { - return priorityA > priorityB ? -1 : 1 - } - const nameA = a.uiMetadata?.displayName || a.name - const nameB = b.uiMetadata?.displayName || b.name - return nameA < nameB ? -1 : 1 - }) - ) - } - - const actions = { - fetch: async () => { - const roles = await API.getRoles() - setRoles(roles) - }, - fetchByAppId: async appId => { - const { roles } = await API.getRolesForApp(appId) - setRoles(roles) - }, - delete: async role => { - await API.deleteRole(role._id, role._rev) - await actions.fetch() - }, - save: async role => { - const savedRole = await API.saveRole(role) - await actions.fetch() - return savedRole - }, - replace: (roleId, role) => { - // Handles external updates of roles - if (!roleId) { - return - } - - // Handle deletion - if (!role) { - store.update(state => state.filter(x => x._id !== roleId)) - return - } - - // Add new role - const index = get(store).findIndex(x => x._id === role._id) - if (index === -1) { - store.update(state => [...state, role]) - } - - // Update existing role - else if (role) { - store.update(state => { - state[index] = role - return [...state] - }) - } - }, - } - - return { - subscribe: enriched.subscribe, - ...actions, - } -} - -export const roles = createRolesStore() diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts new file mode 100644 index 0000000000..ea34fdef53 --- /dev/null +++ b/packages/builder/src/stores/builder/roles.ts @@ -0,0 +1,104 @@ +import { derived, get } from "svelte/store" +import { API } from "@/api" +import { RoleUtils } from "@budibase/frontend-core" +import { BudiStore } from "../BudiStore" +import { Role } from "@budibase/types" + +interface RoleWithMetadata extends Role { + uiMetadata?: { + displayName?: string + color?: string + description?: string + } +} + +export class RoleStore extends BudiStore { + constructor() { + super([]) + } + + enriched = derived(this, $store => { + return $store.map(role => ({ + ...role, + // Ensure we have new metadata for all roles + uiMetadata: { + displayName: role.uiMetadata?.displayName || role.name, + color: + role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", + description: role.uiMetadata?.description || "Custom role", + }, + })) + }) + + private setRoles = (roles: RoleWithMetadata[]) => { + this.set( + roles.sort((a, b) => { + // Ensure we have valid IDs for priority comparison + const priorityA = RoleUtils.getRolePriority(a._id) + const priorityB = RoleUtils.getRolePriority(b._id) + if (priorityA !== priorityB) { + return priorityA > priorityB ? -1 : 1 + } + const nameA = a.uiMetadata?.displayName || a.name + const nameB = b.uiMetadata?.displayName || b.name + return nameA < nameB ? -1 : 1 + }) + ) + } + + fetch = async () => { + const roles = await API.getRoles() + this.setRoles(roles) + } + + fetchByAppId = async (appId: string) => { + const { roles } = await API.getRolesForApp(appId) + this.setRoles(roles) + } + + delete = async (role: RoleWithMetadata) => { + if (!role._id || !role._rev) { + return + } + await API.deleteRole(role._id, role._rev) + await this.fetch() + } + + save = async (role: RoleWithMetadata) => { + const savedRole = await API.saveRole(role) + await this.fetch() + return savedRole + } + + replace = (roleId: string, role?: RoleWithMetadata) => { + // Handles external updates of roles + if (!roleId) { + return + } + + // Handle deletion + if (!role) { + this.update(state => state.filter(x => x._id !== roleId)) + return + } + + // Add new role + const index = get(this).findIndex(x => x._id === role._id) + if (index === -1) { + this.update(state => [...state, role]) + } + // Update existing role + else if (role) { + this.update(state => { + state[index] = role + return [...state] + }) + } + } +} + +const store = new RoleStore() +export const roles = { + ...store, + subscribe: store.enriched.subscribe, +} From 1248e55bc2e2969a9075b3e94f3341da7382e3ee Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 11:35:46 +0000 Subject: [PATCH 30/57] use correct type --- packages/builder/src/stores/builder/roles.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts index ea34fdef53..95ea63a997 100644 --- a/packages/builder/src/stores/builder/roles.ts +++ b/packages/builder/src/stores/builder/roles.ts @@ -4,15 +4,7 @@ import { RoleUtils } from "@budibase/frontend-core" import { BudiStore } from "../BudiStore" import { Role } from "@budibase/types" -interface RoleWithMetadata extends Role { - uiMetadata?: { - displayName?: string - color?: string - description?: string - } -} - -export class RoleStore extends BudiStore { +export class RoleStore extends BudiStore { constructor() { super([]) } @@ -30,7 +22,7 @@ export class RoleStore extends BudiStore { })) }) - private setRoles = (roles: RoleWithMetadata[]) => { + private setRoles = (roles: Role[]) => { this.set( roles.sort((a, b) => { // Ensure we have valid IDs for priority comparison @@ -56,7 +48,7 @@ export class RoleStore extends BudiStore { this.setRoles(roles) } - delete = async (role: RoleWithMetadata) => { + delete = async (role: Role) => { if (!role._id || !role._rev) { return } @@ -64,13 +56,13 @@ export class RoleStore extends BudiStore { await this.fetch() } - save = async (role: RoleWithMetadata) => { + save = async (role: Role) => { const savedRole = await API.saveRole(role) await this.fetch() return savedRole } - replace = (roleId: string, role?: RoleWithMetadata) => { + replace = (roleId: string, role?: Role) => { // Handles external updates of roles if (!roleId) { return From a58c75e328f0b4aa0f2ebfb47a1df3275d2b541d Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 6 Jan 2025 12:11:14 +0000 Subject: [PATCH 31/57] Expose feature flags type in packages/type so it can be exposed to the frontend. --- .../backend-core/src/context/mainContext.ts | 8 +- packages/backend-core/src/context/types.ts | 2 +- .../backend-core/src/features/features.ts | 135 ++++-------------- .../src/features/tests/features.spec.ts | 28 +--- packages/pro | 2 +- .../src/api/controllers/row/staticFormula.ts | 4 +- packages/server/src/automations/actions.ts | 6 +- .../server/src/automations/steps/openai.ts | 4 +- .../server/src/middleware/zod-validator.ts | 2 +- packages/types/src/api/web/global/self.ts | 3 +- packages/types/src/sdk/featureFlag.ts | 10 +- .../worker/src/api/controllers/global/self.ts | 3 +- 12 files changed, 57 insertions(+), 150 deletions(-) diff --git a/packages/backend-core/src/context/mainContext.ts b/packages/backend-core/src/context/mainContext.ts index 64ba240fa5..e5f20882d3 100644 --- a/packages/backend-core/src/context/mainContext.ts +++ b/packages/backend-core/src/context/mainContext.ts @@ -385,17 +385,17 @@ export function getCurrentContext(): ContextMap | undefined { } } -export function getFeatureFlags>( +export function getFeatureFlags( key: string -): T | undefined { +): Record | undefined { const context = getCurrentContext() if (!context) { return undefined } - return context.featureFlagCache?.[key] as T + return context.featureFlagCache?.[key] } -export function setFeatureFlags(key: string, value: Record) { +export function setFeatureFlags(key: string, value: Record) { const context = getCurrentContext() if (!context) { return diff --git a/packages/backend-core/src/context/types.ts b/packages/backend-core/src/context/types.ts index 5549a47ff7..23598b951e 100644 --- a/packages/backend-core/src/context/types.ts +++ b/packages/backend-core/src/context/types.ts @@ -20,7 +20,7 @@ export type ContextMap = { clients: Record } featureFlagCache?: { - [key: string]: Record + [key: string]: Record } viewToTableCache?: Record } diff --git a/packages/backend-core/src/features/features.ts b/packages/backend-core/src/features/features.ts index 650254fcb2..772bcf5860 100644 --- a/packages/backend-core/src/features/features.ts +++ b/packages/backend-core/src/features/features.ts @@ -2,9 +2,10 @@ import env from "../environment" import * as crypto from "crypto" import * as context from "../context" import { PostHog, PostHogOptions } from "posthog-node" -import { FeatureFlag } from "@budibase/types" import tracer from "dd-trace" import { Duration } from "../utils" +import { cloneDeep } from "lodash" +import { FeatureFlagDefaults } from "@budibase/types" let posthog: PostHog | undefined export function init(opts?: PostHogOptions) { @@ -30,74 +31,6 @@ export function shutdown() { posthog?.shutdown() } -export abstract class Flag { - static boolean(defaultValue: boolean): Flag { - return new BooleanFlag(defaultValue) - } - - static string(defaultValue: string): Flag { - return new StringFlag(defaultValue) - } - - static number(defaultValue: number): Flag { - return new NumberFlag(defaultValue) - } - - protected constructor(public defaultValue: T) {} - - abstract parse(value: any): T -} - -type UnwrapFlag = F extends Flag ? U : never - -export type FlagValues = { - [K in keyof T]: UnwrapFlag -} - -type KeysOfType = { - [K in keyof T]: T[K] extends Flag ? K : never -}[keyof T] - -class BooleanFlag extends Flag { - parse(value: any) { - if (typeof value === "string") { - return ["true", "t", "1"].includes(value.toLowerCase()) - } - - if (typeof value === "boolean") { - return value - } - - throw new Error(`could not parse value "${value}" as boolean`) - } -} - -class StringFlag extends Flag { - parse(value: any) { - if (typeof value === "string") { - return value - } - throw new Error(`could not parse value "${value}" as string`) - } -} - -class NumberFlag extends Flag { - parse(value: any) { - if (typeof value === "number") { - return value - } - - if (typeof value === "string") { - const parsed = parseFloat(value) - if (!isNaN(parsed)) { - return parsed - } - } - - throw new Error(`could not parse value "${value}" as number`) - } -} - export interface EnvFlagEntry { tenantId: string key: string @@ -120,7 +53,7 @@ export function parseEnvFlags(flags: string): EnvFlagEntry[] { return result } -export class FlagSet, T extends { [key: string]: V }> { +export class FlagSet { // This is used to safely cache flags sets in the current request context. // Because multiple sets could theoretically exist, we don't want the cache of // one to leak into another. @@ -130,34 +63,25 @@ export class FlagSet, T extends { [key: string]: V }> { this.setId = crypto.randomUUID() } - defaults(): FlagValues { - return Object.keys(this.flagSchema).reduce((acc, key) => { - const typedKey = key as keyof T - acc[typedKey] = this.flagSchema[key].defaultValue - return acc - }, {} as FlagValues) + defaults(): T { + return cloneDeep(this.flagSchema) } isFlagName(name: string | number | symbol): name is keyof T { return this.flagSchema[name as keyof T] !== undefined } - async get(key: K): Promise[K]> { + async isEnabled(key: K): Promise { const flags = await this.fetch() return flags[key] } - async isEnabled>(key: K): Promise { - const flags = await this.fetch() - return flags[key] - } - - async fetch(): Promise> { + async fetch(): Promise { return await tracer.trace("features.fetch", async span => { - const cachedFlags = context.getFeatureFlags>(this.setId) + const cachedFlags = context.getFeatureFlags(this.setId) if (cachedFlags) { span?.addTags({ fromCache: true }) - return cachedFlags + return cachedFlags as T } const tags: Record = {} @@ -189,7 +113,7 @@ export class FlagSet, T extends { [key: string]: V }> { // @ts-expect-error - TS does not like you writing into a generic type, // but we know that it's okay in this case because it's just an object. - flagValues[key as keyof FlagValues] = value + flagValues[key as keyof T] = value tags[`flags.${key}.source`] = "environment" } @@ -217,11 +141,11 @@ export class FlagSet, T extends { [key: string]: V }> { tags[`readFromPostHog`] = true const personProperties: Record = { tenantId } - const posthogFlags = await posthog.getAllFlagsAndPayloads(userId, { + const posthogFlags = await posthog.getAllFlags(userId, { personProperties, }) - for (const [name, value] of Object.entries(posthogFlags.featureFlags)) { + for (const [name, value] of Object.entries(posthogFlags)) { if (!this.isFlagName(name)) { // We don't want an unexpected PostHog flag to break the app, so we // just log it and continue. @@ -229,19 +153,20 @@ export class FlagSet, T extends { [key: string]: V }> { continue } + if (typeof value !== "boolean") { + console.warn(`Invalid value for posthog flag "${name}": ${value}`) + continue + } + if (flagValues[name] === true || specificallySetFalse.has(name)) { // If the flag is already set to through environment variables, we // don't want to override it back to false here. continue } - const payload = posthogFlags.featureFlagPayloads?.[name] - const flag = this.flagSchema[name] try { - // @ts-expect-error - TS does not like you writing into a generic - // type, but we know that it's okay in this case because it's just - // an object. - flagValues[name] = flag.parse(payload || value) + // @ts-expect-error - TS does not like you writing into a generic type. + flagValues[name] = value tags[`flags.${name}.source`] = "posthog" } catch (err) { // We don't want an invalid PostHog flag to break the app, so we just @@ -262,18 +187,12 @@ export class FlagSet, T extends { [key: string]: V }> { } } -// This is the primary source of truth for feature flags. If you want to add a -// new flag, add it here and use the `fetch` and `get` functions to access it. -// All of the machinery in this file is to make sure that flags have their -// default values set correctly and their types flow through the system. -const flagsConfig: Record> = { - [FeatureFlag.DEFAULT_VALUES]: Flag.boolean(true), - [FeatureFlag.AUTOMATION_BRANCHING]: Flag.boolean(true), - [FeatureFlag.AI_CUSTOM_CONFIGS]: Flag.boolean(true), - [FeatureFlag.BUDIBASE_AI]: Flag.boolean(true), - [FeatureFlag.USE_ZOD_VALIDATOR]: Flag.boolean(env.isDev()), -} -export const flags = new FlagSet(flagsConfig) +export const flags = new FlagSet(FeatureFlagDefaults) -type UnwrapPromise = T extends Promise ? U : T -export type FeatureFlags = UnwrapPromise> +export async function isEnabled(flag: keyof typeof FeatureFlagDefaults) { + return await flags.isEnabled(flag) +} + +export async function all() { + return await flags.fetch() +} diff --git a/packages/backend-core/src/features/tests/features.spec.ts b/packages/backend-core/src/features/tests/features.spec.ts index ced874f4af..f918347eea 100644 --- a/packages/backend-core/src/features/tests/features.spec.ts +++ b/packages/backend-core/src/features/tests/features.spec.ts @@ -1,5 +1,5 @@ import { IdentityContext, IdentityType } from "@budibase/types" -import { Flag, FlagSet, FlagValues, init, shutdown } from "../" +import { FlagSet, init, shutdown } from "../" import * as context from "../../context" import environment, { withEnv } from "../../environment" import nodeFetch from "node-fetch" @@ -7,10 +7,8 @@ import nock from "nock" import * as crypto from "crypto" const schema = { - TEST_BOOLEAN: Flag.boolean(false), - TEST_STRING: Flag.string("default value"), - TEST_NUMBER: Flag.number(0), - TEST_BOOLEAN_DEFAULT_TRUE: Flag.boolean(true), + TEST_BOOLEAN: false, + TEST_BOOLEAN_DEFAULT_TRUE: true, } const flags = new FlagSet(schema) @@ -19,7 +17,7 @@ interface TestCase { identity?: Partial environmentFlags?: string posthogFlags?: PostHogFlags - expected?: Partial> + expected?: Partial errorMessage?: string | RegExp } @@ -83,22 +81,6 @@ describe("feature flags", () => { }, expected: { TEST_BOOLEAN: true }, }, - { - it: "should be able to read string flags from PostHog", - posthogFlags: { - featureFlags: { TEST_STRING: true }, - featureFlagPayloads: { TEST_STRING: "test" }, - }, - expected: { TEST_STRING: "test" }, - }, - { - it: "should be able to read numeric flags from PostHog", - posthogFlags: { - featureFlags: { TEST_NUMBER: true }, - featureFlagPayloads: { TEST_NUMBER: "123" }, - }, - expected: { TEST_NUMBER: 123 }, - }, { it: "should not be able to override a negative environment flag from PostHog", environmentFlags: "default:!TEST_BOOLEAN", @@ -177,7 +159,7 @@ describe("feature flags", () => { expect(values).toMatchObject(expected) for (const [key, expectedValue] of Object.entries(expected)) { - const value = await flags.get(key as keyof typeof schema) + const value = await flags.isEnabled(key as keyof typeof schema) expect(value).toBe(expectedValue) } } else { diff --git a/packages/pro b/packages/pro index ae786121d9..9091868986 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit ae786121d923449b0ad5fcbd123d0a9fec28f65e +Subproject commit 9091868986fbc6aae580280f48853482e0b06c6a diff --git a/packages/server/src/api/controllers/row/staticFormula.ts b/packages/server/src/api/controllers/row/staticFormula.ts index 4464b7f44a..b81a164807 100644 --- a/packages/server/src/api/controllers/row/staticFormula.ts +++ b/packages/server/src/api/controllers/row/staticFormula.ts @@ -163,9 +163,9 @@ export async function finaliseRow( contextRows: [enrichedRow], }) const aiEnabled = - ((await features.flags.isEnabled(FeatureFlag.BUDIBASE_AI)) && + ((await features.isEnabled(FeatureFlag.BUDIBASE_AI)) && (await pro.features.isBudibaseAIEnabled())) || - ((await features.flags.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) && + ((await features.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) && (await pro.features.isAICustomConfigsEnabled())) if (aiEnabled) { row = await processAIColumns(table, row, { diff --git a/packages/server/src/automations/actions.ts b/packages/server/src/automations/actions.ts index e5a1c63b7d..1c201d1f64 100644 --- a/packages/server/src/automations/actions.ts +++ b/packages/server/src/automations/actions.ts @@ -105,13 +105,13 @@ if (env.SELF_HOSTED) { export async function getActionDefinitions(): Promise< Record > { - if (await features.flags.isEnabled(FeatureFlag.AUTOMATION_BRANCHING)) { + if (await features.isEnabled(FeatureFlag.AUTOMATION_BRANCHING)) { BUILTIN_ACTION_DEFINITIONS["BRANCH"] = branch.definition } if ( env.SELF_HOSTED || - (await features.flags.isEnabled(FeatureFlag.BUDIBASE_AI)) || - (await features.flags.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) + (await features.isEnabled(FeatureFlag.BUDIBASE_AI)) || + (await features.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) ) { BUILTIN_ACTION_DEFINITIONS["OPENAI"] = openai.definition } diff --git a/packages/server/src/automations/steps/openai.ts b/packages/server/src/automations/steps/openai.ts index 48eaa93057..19595cc0d0 100644 --- a/packages/server/src/automations/steps/openai.ts +++ b/packages/server/src/automations/steps/openai.ts @@ -100,10 +100,10 @@ export async function run({ try { let response const customConfigsEnabled = - (await features.flags.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) && + (await features.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) && (await pro.features.isAICustomConfigsEnabled()) const budibaseAIEnabled = - (await features.flags.isEnabled(FeatureFlag.BUDIBASE_AI)) && + (await features.isEnabled(FeatureFlag.BUDIBASE_AI)) && (await pro.features.isBudibaseAIEnabled()) let llmWrapper diff --git a/packages/server/src/middleware/zod-validator.ts b/packages/server/src/middleware/zod-validator.ts index e8cc2c470a..d57e1c48ff 100644 --- a/packages/server/src/middleware/zod-validator.ts +++ b/packages/server/src/middleware/zod-validator.ts @@ -7,7 +7,7 @@ import { fromZodError } from "zod-validation-error" function validate(schema: AnyZodObject, property: "body" | "params") { // Return a Koa middleware function return async (ctx: Ctx, next: any) => { - if (!(await features.flags.isEnabled(FeatureFlag.USE_ZOD_VALIDATOR))) { + if (!(await features.isEnabled(FeatureFlag.USE_ZOD_VALIDATOR))) { return next() } diff --git a/packages/types/src/api/web/global/self.ts b/packages/types/src/api/web/global/self.ts index 5f21a8ddc5..d2c79bdba3 100644 --- a/packages/types/src/api/web/global/self.ts +++ b/packages/types/src/api/web/global/self.ts @@ -1,3 +1,4 @@ +import { FeatureFlags } from "packages/types/src/sdk" import { DevInfo, User } from "../../../documents" export interface GenerateAPIKeyRequest { @@ -8,5 +9,5 @@ export interface GenerateAPIKeyResponse extends DevInfo {} export interface FetchAPIKeyResponse extends DevInfo {} export interface GetGlobalSelfResponse extends User { - flags?: Record + flags?: FeatureFlags } diff --git a/packages/types/src/sdk/featureFlag.ts b/packages/types/src/sdk/featureFlag.ts index 98e744324c..725ae0feb1 100644 --- a/packages/types/src/sdk/featureFlag.ts +++ b/packages/types/src/sdk/featureFlag.ts @@ -6,6 +6,12 @@ export enum FeatureFlag { USE_ZOD_VALIDATOR = "USE_ZOD_VALIDATOR", } -export interface TenantFeatureFlags { - [key: string]: FeatureFlag[] +export const FeatureFlagDefaults = { + [FeatureFlag.DEFAULT_VALUES]: true, + [FeatureFlag.AUTOMATION_BRANCHING]: true, + [FeatureFlag.AI_CUSTOM_CONFIGS]: true, + [FeatureFlag.BUDIBASE_AI]: true, + [FeatureFlag.USE_ZOD_VALIDATOR]: false, } + +export type FeatureFlags = typeof FeatureFlagDefaults diff --git a/packages/worker/src/api/controllers/global/self.ts b/packages/worker/src/api/controllers/global/self.ts index f8488f526b..eb704ccf02 100644 --- a/packages/worker/src/api/controllers/global/self.ts +++ b/packages/worker/src/api/controllers/global/self.ts @@ -111,8 +111,7 @@ export async function getSelf(ctx: UserCtx) { ctx.body = await groups.enrichUserRolesFromGroups(user) // add the feature flags for this tenant - const flags = await features.flags.fetch() - ctx.body.flags = flags + ctx.body.flags = await features.flags.fetch() addSessionAttributesToUser(ctx) } From c3564528b7c989e8069449251d474651ee9cb2c7 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 6 Jan 2025 12:15:41 +0000 Subject: [PATCH 32/57] Fix types. --- packages/backend-core/src/features/tests/utils.ts | 3 ++- packages/types/src/api/web/global/self.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/src/features/tests/utils.ts b/packages/backend-core/src/features/tests/utils.ts index cc633c083d..b9281b7f19 100644 --- a/packages/backend-core/src/features/tests/utils.ts +++ b/packages/backend-core/src/features/tests/utils.ts @@ -1,5 +1,6 @@ -import { FeatureFlags, parseEnvFlags } from ".." +import { FeatureFlags } from "@budibase/types" import { setEnv } from "../../environment" +import { parseEnvFlags } from "../features" function getCurrentFlags(): Record> { const result: Record> = {} diff --git a/packages/types/src/api/web/global/self.ts b/packages/types/src/api/web/global/self.ts index d2c79bdba3..9e879e6c3c 100644 --- a/packages/types/src/api/web/global/self.ts +++ b/packages/types/src/api/web/global/self.ts @@ -1,4 +1,4 @@ -import { FeatureFlags } from "packages/types/src/sdk" +import { FeatureFlags } from "@budibase/types" import { DevInfo, User } from "../../../documents" export interface GenerateAPIKeyRequest { From 867d162751d9fa75745cde7f317572d3857f376e Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:34:38 +0000 Subject: [PATCH 33/57] convert published store to ts --- .../src/stores/builder/{published.js => published.ts} | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) rename packages/builder/src/stores/builder/{published.js => published.ts} (53%) diff --git a/packages/builder/src/stores/builder/published.js b/packages/builder/src/stores/builder/published.ts similarity index 53% rename from packages/builder/src/stores/builder/published.js rename to packages/builder/src/stores/builder/published.ts index a59352fb22..c38f3bb718 100644 --- a/packages/builder/src/stores/builder/published.js +++ b/packages/builder/src/stores/builder/published.ts @@ -1,13 +1,16 @@ import { appStore } from "./app" import { appsStore } from "@/stores/portal/apps" import { deploymentStore } from "./deployments" -import { derived } from "svelte/store" +import { derived, type Readable } from "svelte/store" +import { DeploymentProgressResponse, DeploymentStatus } from "@budibase/types" -export const appPublished = derived( +export const appPublished: Readable = derived( [appStore, appsStore, deploymentStore], ([$appStore, $appsStore, $deploymentStore]) => { const app = $appsStore.apps.find(app => app.devId === $appStore.appId) - const deployments = $deploymentStore.filter(x => x.status === "SUCCESS") + const deployments = $deploymentStore.filter( + (x: DeploymentProgressResponse) => x.status === DeploymentStatus.SUCCESS + ) return app?.status === "published" && deployments.length > 0 } ) From 511328002ee5ff4a33c73df764b3528468eed37d Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 6 Jan 2025 12:35:55 +0000 Subject: [PATCH 34/57] Update pro reference. --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 9091868986..32d84f109d 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 9091868986fbc6aae580280f48853482e0b06c6a +Subproject commit 32d84f109d4edc526145472a7446327312151442 From 17bb67f6252de70c8679a2852005f6d6647adc54 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:41:40 +0000 Subject: [PATCH 35/57] type theme correctly in app document --- packages/builder/src/stores/builder/theme.ts | 15 +++------------ packages/types/src/documents/app/app.ts | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/stores/builder/theme.ts b/packages/builder/src/stores/builder/theme.ts index b3ac202a5d..f2675fe06b 100644 --- a/packages/builder/src/stores/builder/theme.ts +++ b/packages/builder/src/stores/builder/theme.ts @@ -19,10 +19,7 @@ export class ThemeStore extends BudiStore { syncAppTheme = (app: App) => { this.update(state => { - const theme = ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme + const theme = ensureValidTheme(app.theme, DefaultAppTheme) return { ...state, theme, @@ -35,10 +32,7 @@ export class ThemeStore extends BudiStore { const app = await API.saveAppMetadata(appId, { theme }) this.update(state => ({ ...state, - theme: ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(app.theme, DefaultAppTheme), })) } @@ -55,10 +49,7 @@ export class ThemeStore extends BudiStore { const { theme, customTheme } = metadata this.update(state => ({ ...state, - theme: ensureValidTheme( - theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(theme, DefaultAppTheme), customTheme: customTheme || {}, })) } diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index e31dd1e9ac..7486a3fa7e 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -1,4 +1,4 @@ -import { User, Document, Plugin, Snippet } from "../" +import { User, Document, Plugin, Snippet, Theme } from "../" import { SocketSession } from "../../sdk" export type AppMetadataErrors = { [key: string]: string[] } @@ -14,7 +14,7 @@ export interface App extends Document { instance: AppInstance tenantId: string status: string - theme?: string + theme?: Theme customTheme?: AppCustomTheme revertableVersion?: string lockedBy?: User From a09caf52d8c3fe4bd19f853f10cc30f5f3969ce5 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:43:15 +0000 Subject: [PATCH 36/57] remove unnecessary casts --- packages/builder/src/stores/builder/theme.ts | 15 +++------------ packages/types/src/documents/app/app.ts | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/stores/builder/theme.ts b/packages/builder/src/stores/builder/theme.ts index b3ac202a5d..f2675fe06b 100644 --- a/packages/builder/src/stores/builder/theme.ts +++ b/packages/builder/src/stores/builder/theme.ts @@ -19,10 +19,7 @@ export class ThemeStore extends BudiStore { syncAppTheme = (app: App) => { this.update(state => { - const theme = ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme + const theme = ensureValidTheme(app.theme, DefaultAppTheme) return { ...state, theme, @@ -35,10 +32,7 @@ export class ThemeStore extends BudiStore { const app = await API.saveAppMetadata(appId, { theme }) this.update(state => ({ ...state, - theme: ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(app.theme, DefaultAppTheme), })) } @@ -55,10 +49,7 @@ export class ThemeStore extends BudiStore { const { theme, customTheme } = metadata this.update(state => ({ ...state, - theme: ensureValidTheme( - theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(theme, DefaultAppTheme), customTheme: customTheme || {}, })) } diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index e31dd1e9ac..7486a3fa7e 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -1,4 +1,4 @@ -import { User, Document, Plugin, Snippet } from "../" +import { User, Document, Plugin, Snippet, Theme } from "../" import { SocketSession } from "../../sdk" export type AppMetadataErrors = { [key: string]: string[] } @@ -14,7 +14,7 @@ export interface App extends Document { instance: AppInstance tenantId: string status: string - theme?: string + theme?: Theme customTheme?: AppCustomTheme revertableVersion?: string lockedBy?: User From 48948712b9438042704dcb4facbdb3228f197007 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:53:10 +0000 Subject: [PATCH 37/57] remove further cast --- packages/builder/src/stores/builder/theme.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/stores/builder/theme.ts b/packages/builder/src/stores/builder/theme.ts index f2675fe06b..604add9410 100644 --- a/packages/builder/src/stores/builder/theme.ts +++ b/packages/builder/src/stores/builder/theme.ts @@ -12,7 +12,7 @@ interface ThemeState { export class ThemeStore extends BudiStore { constructor() { super({ - theme: DefaultAppTheme as Theme, + theme: DefaultAppTheme, customTheme: {}, }) } From 30b543b6b727f25d46ec5d19a26091c76eb9b901 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 13:35:00 +0000 Subject: [PATCH 38/57] error message for no row action name --- packages/builder/src/stores/builder/rowActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/stores/builder/rowActions.ts b/packages/builder/src/stores/builder/rowActions.ts index 378579e41b..9576eccd1b 100644 --- a/packages/builder/src/stores/builder/rowActions.ts +++ b/packages/builder/src/stores/builder/rowActions.ts @@ -66,7 +66,7 @@ export class RowActionStore extends BudiStore { } if (!name) { - return + throw new Error("Failed to generate a unique name for the row action") } // Create the action From 9f712eda71eba4c2bf6092e1cabfd38bf27e97c0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 6 Jan 2025 13:36:56 +0000 Subject: [PATCH 39/57] Revert pro change --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index ae786121d9..32d84f109d 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit ae786121d923449b0ad5fcbd123d0a9fec28f65e +Subproject commit 32d84f109d4edc526145472a7446327312151442 From ab3bf05dfefe22520e8bedd601134ba6275f9710 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 6 Jan 2025 13:37:55 +0000 Subject: [PATCH 40/57] Make store terser --- packages/builder/src/stores/portal/featureFlags.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/builder/src/stores/portal/featureFlags.ts b/packages/builder/src/stores/portal/featureFlags.ts index ab0b178ab4..0e40d0c7b4 100644 --- a/packages/builder/src/stores/portal/featureFlags.ts +++ b/packages/builder/src/stores/portal/featureFlags.ts @@ -2,12 +2,7 @@ import { derived, Readable } from "svelte/store" import { auth } from "@/stores/portal" import { FeatureFlags, FeatureFlagDefaults } from "@budibase/types" -export const featureFlags: Readable = derived( - [auth], - ([$auth]) => { - return { - ...FeatureFlagDefaults, - ...($auth?.user?.flags || {}), - } - } -) +export const featureFlags: Readable = derived(auth, $auth => ({ + ...FeatureFlagDefaults, + ...($auth?.user?.flags || {}), +})) From 34b9cf38cf733b89256e31c6a0bd78dc3cc5ec16 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 6 Jan 2025 14:50:57 +0000 Subject: [PATCH 41/57] Add the openAPI package globally to avoid issues with it not being found. --- .github/workflows/readme-openapi.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/readme-openapi.yml b/.github/workflows/readme-openapi.yml index b52787934f..9f42f6141b 100644 --- a/.github/workflows/readme-openapi.yml +++ b/.github/workflows/readme-openapi.yml @@ -19,5 +19,8 @@ jobs: cache: yarn - run: yarn --frozen-lockfile + - name: Install OpenAPI pkg + run: yarn global add openapi + - name: update specs run: cd packages/server && yarn specs && openapi specs/openapi.yaml --key=${{ secrets.README_API_KEY }} --id=6728a74f5918b50036c61841 From 294f696d63cc66250742c7d3dd7f4b619698f566 Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:31:39 +0000 Subject: [PATCH 42/57] Offer option to open Budibase via CLI (#15312) --- packages/cli/package.json | 3 ++- packages/cli/src/hosting/start.ts | 5 +++++ yarn.lock | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 927824a522..662434957e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@budibase/backend-core": "*", + "@budibase/pouchdb-replication-stream": "1.2.11", "@budibase/string-templates": "*", "@budibase/types": "*", "chalk": "4.1.0", @@ -28,9 +29,9 @@ "inquirer": "8.0.0", "lookpath": "1.1.0", "node-fetch": "2.6.7", + "open": "8.4.2", "posthog-node": "4.0.1", "pouchdb": "7.3.0", - "@budibase/pouchdb-replication-stream": "1.2.11", "randomstring": "1.1.5", "tar": "6.2.1", "yaml": "^2.1.1" diff --git a/packages/cli/src/hosting/start.ts b/packages/cli/src/hosting/start.ts index 75e3df451f..5b08268c94 100644 --- a/packages/cli/src/hosting/start.ts +++ b/packages/cli/src/hosting/start.ts @@ -3,6 +3,8 @@ import { info, success } from "../utils" import * as makeFiles from "./makeFiles" import compose from "docker-compose" import fs from "fs" +import { confirmation } from "../questions" +const open = require("open") export async function start() { await checkDockerConfigured() @@ -22,6 +24,9 @@ export async function start() { // need to log as it makes it more clear await compose.upAll({ cwd: "./", log: true }) }) + if (await confirmation(`Do you wish to open http://localhost:${port} ?`)) { + await open(`http://localhost:${port}`) + } console.log( success( `Services started, please go to http://localhost:${port} for next steps.` diff --git a/yarn.lock b/yarn.lock index c6181f7866..c54385478e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2131,9 +2131,9 @@ through2 "^2.0.0" "@budibase/pro@npm:@budibase/pro@latest": - version "3.2.28" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.28.tgz#59b5b37225715bb8fbf5b1c5c989140b10b58710" - integrity sha512-eDPeZpYFRZYQhCulcQAUwFoPk68c8+K9mIsB6QD3oMHmHTDA1P2ZcXvLNqDTIqHB94DqnWinqDf4hTuGYApgPA== + version "3.2.32" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.32.tgz#f6abcd5a5524e7f33d958acb6e610e29995427bb" + integrity sha512-bF0pd17IjYugjll2yKYmb0RM+tfKZcCmRBc4XG2NZ4f/I47QaOovm9RqSw6tfqCFuzRewxR3SWmtmSseUc/e0w== dependencies: "@anthropic-ai/sdk" "^0.27.3" "@budibase/backend-core" "*" @@ -15600,15 +15600,7 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== -open@^7.3.1: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== - dependencies: - is-docker "^2.0.0" - is-wsl "^2.1.1" - -open@^8.0.0, open@^8.4.0, open@~8.4.0: +open@8.4.2, open@^8.0.0, open@^8.4.0, open@~8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -15617,6 +15609,14 @@ open@^8.0.0, open@^8.4.0, open@~8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" +open@^7.3.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + openai@4.59.0: version "4.59.0" resolved "https://registry.yarnpkg.com/openai/-/openai-4.59.0.tgz#3961d11a9afb5920e1bd475948a87969e244fc08" From 80a77d28a292bf56b7eeb55f13b07abfbe69d0d0 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 6 Jan 2025 17:37:58 +0000 Subject: [PATCH 43/57] PR comment fixes. --- .../src/objectStore/buckets/tests/app.spec.ts | 36 +++++++++++++++++++ .../objectStore/buckets/tests/global.spec.ts | 30 ++++++++++++++++ .../src/objectStore/objectStore.ts | 19 +++++----- 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index d188d774bb..e36b36d39d 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -93,6 +93,22 @@ describe("app", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + const url = await getAppFileUrl() + expect(url).toBe( + "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + const url = await getAppFileUrl() + expect(url).toBe( + "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getAppFileUrl() @@ -108,6 +124,26 @@ describe("app", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + await testEnv.withTenant(async () => { + const url = await getAppFileUrl() + expect(url).toBe( + "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + await testEnv.withTenant(async () => { + const url = await getAppFileUrl() + expect(url).toBe( + "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async () => { diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index 9d5ec07c7a..c98d98e016 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -12,6 +12,18 @@ describe("global", () => { testEnv.singleTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + const url = await getGlobalFileUrl() + expect(url).toBe("/files/signed/global/settings/logoUrl") + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + const url = await getGlobalFileUrl() + expect(url).toBe("http://s3.example.com/global/settings/logoUrl") + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getGlobalFileUrl() @@ -27,6 +39,24 @@ describe("global", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + await testEnv.withTenant(async tenantId => { + const url = await getGlobalFileUrl() + expect(url).toBe(`/files/signed/global/${tenantId}/settings/logoUrl`) + }) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + await testEnv.withTenant(async tenantId => { + const url = await getGlobalFileUrl() + expect(url).toBe( + `http://s3.example.com/global/${tenantId}/settings/logoUrl` + ) + }) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async tenantId => { diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index adc974a131..4f07abe7e2 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -23,6 +23,7 @@ import { v4 } from "uuid" import { APP_PREFIX, APP_DEV_PREFIX } from "../db" import fsp from "fs/promises" import { ReadableStream } from "stream/web" +import { NodeJsRuntimeStreamingBlobPayloadOutputTypes } from "@smithy/types" const streamPipeline = promisify(stream.pipeline) // use this as a temporary store of buckets that are being created @@ -194,17 +195,17 @@ export async function upload({ } let contentType = type - if (!contentType) { - contentType = extension - ? CONTENT_TYPE_MAP[extension.toLowerCase()] - : CONTENT_TYPE_MAP.txt - } + const finalContentType = contentType + ? contentType + : extension + ? CONTENT_TYPE_MAP[extension.toLowerCase()] + : CONTENT_TYPE_MAP.txt const config: PutObjectCommandInput = { // windows file paths need to be converted to forward slashes for s3 Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filename), Body: fileBytes as stream.Readable | Buffer, - ContentType: contentType!, + ContentType: finalContentType, } if (metadata && typeof metadata === "object") { // remove any nullish keys from the metadata object, as these may be considered invalid @@ -310,11 +311,13 @@ export async function retrieve( if (!response.Body) { throw new Error("Unable to retrieve object") } + const nodeResponse = + response.Body as NodeJsRuntimeStreamingBlobPayloadOutputTypes // currently these are all strings if (STRING_CONTENT_TYPES.includes(response.ContentType)) { - return response.Body.toString() + return nodeResponse.toString() } else { - return response.Body as stream.Readable + return nodeResponse } } From 766d095c9c3b38d34bd09bd0b6fce635e990a690 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 6 Jan 2025 17:53:14 +0000 Subject: [PATCH 44/57] Adding dependency. --- packages/backend-core/package.json | 1 + yarn.lock | 44 ++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 4339ee0a94..b380fca017 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -74,6 +74,7 @@ "devDependencies": { "@jest/types": "^29.6.3", "@shopify/jest-koa-mocks": "5.1.1", + "@smithy/types": "4.0.0", "@swc/core": "1.3.71", "@swc/jest": "0.2.27", "@types/chance": "1.1.3", diff --git a/yarn.lock b/yarn.lock index 599f5cdf2f..fbae35bf36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2778,9 +2778,9 @@ through2 "^2.0.0" "@budibase/pro@npm:@budibase/pro@latest": - version "3.2.28" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.28.tgz#59b5b37225715bb8fbf5b1c5c989140b10b58710" - integrity sha512-eDPeZpYFRZYQhCulcQAUwFoPk68c8+K9mIsB6QD3oMHmHTDA1P2ZcXvLNqDTIqHB94DqnWinqDf4hTuGYApgPA== + version "3.2.32" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-3.2.32.tgz#f6abcd5a5524e7f33d958acb6e610e29995427bb" + integrity sha512-bF0pd17IjYugjll2yKYmb0RM+tfKZcCmRBc4XG2NZ4f/I47QaOovm9RqSw6tfqCFuzRewxR3SWmtmSseUc/e0w== dependencies: "@anthropic-ai/sdk" "^0.27.3" "@budibase/backend-core" "*" @@ -5512,6 +5512,13 @@ "@smithy/util-stream" "^3.3.2" tslib "^2.6.2" +"@smithy/types@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.0.0.tgz#7458c1c4dde3c6cf23221370acf5acd03215de6e" + integrity sha512-aNwIGSOgDOhtTRY/rrn2aeuQeKw/IFrQ998yK5l6Ah853WeWIEmFPs/EO4OpfADEdcK+igWnZytm/oUgkLgUYg== + dependencies: + tslib "^2.6.2" + "@smithy/types@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.2.0.tgz#9dc65767b0ee3d6681704fcc67665d6fc9b6a34e" @@ -19709,7 +19716,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -19801,7 +19817,7 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -19815,6 +19831,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -21562,7 +21585,7 @@ worker-farm@1.7.0: dependencies: errno "~0.1.7" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -21580,6 +21603,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 62873dedf480be50e3d70aa5daef7ad1b2ed160e Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 7 Jan 2025 10:35:07 +0000 Subject: [PATCH 45/57] make roles derived store --- packages/builder/src/stores/builder/roles.ts | 44 ++++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts index 95ea63a997..732f50d6be 100644 --- a/packages/builder/src/stores/builder/roles.ts +++ b/packages/builder/src/stores/builder/roles.ts @@ -1,28 +1,30 @@ -import { derived, get } from "svelte/store" +import { derived, get, type Writable } from "svelte/store" import { API } from "@/api" import { RoleUtils } from "@budibase/frontend-core" -import { BudiStore } from "../BudiStore" +import { DerivedBudiStore } from "../BudiStore" import { Role } from "@budibase/types" -export class RoleStore extends BudiStore { +export class RoleStore extends DerivedBudiStore { constructor() { - super([]) + const makeDerivedStore = (store: Writable) => + derived(store, $store => { + return $store.map((role: Role) => ({ + ...role, + // Ensure we have new metadata for all roles + uiMetadata: { + displayName: role.uiMetadata?.displayName || role.name, + color: + role.uiMetadata?.color || + "var(--spectrum-global-color-magenta-400)", + description: role.uiMetadata?.description || "Custom role", + }, + })) + }) + + super([], makeDerivedStore) } - enriched = derived(this, $store => { - return $store.map(role => ({ - ...role, - // Ensure we have new metadata for all roles - uiMetadata: { - displayName: role.uiMetadata?.displayName || role.name, - color: - role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", - description: role.uiMetadata?.description || "Custom role", - }, - })) - }) - - private setRoles = (roles: Role[]) => { + setRoles = (roles: Role[]) => { this.set( roles.sort((a, b) => { // Ensure we have valid IDs for priority comparison @@ -89,8 +91,4 @@ export class RoleStore extends BudiStore { } } -const store = new RoleStore() -export const roles = { - ...store, - subscribe: store.enriched.subscribe, -} +export const roles = new RoleStore() From 47e0913c54c3329f840bfee5f9ae43212541aa0a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 7 Jan 2025 12:27:29 +0000 Subject: [PATCH 46/57] Use find/splice instead of filter --- packages/builder/src/stores/portal/groups.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/stores/portal/groups.ts b/packages/builder/src/stores/portal/groups.ts index edb7ae7318..028f300d2c 100644 --- a/packages/builder/src/stores/portal/groups.ts +++ b/packages/builder/src/stores/portal/groups.ts @@ -47,9 +47,12 @@ class GroupStore extends BudiStore { async delete(group: UserGroup) { await API.deleteGroup(group._id!, group._rev!) - this.update(state => { - state = state.filter(state => state._id !== group._id) - return state + this.update(groups => { + const index = groups.findIndex(g => g._id === group._id) + if (index !== -1) { + groups.splice(index, 1) + } + return groups }) } From 19f39af9ec4cc0cee2667f7a3c0eb4b29f83f0fd Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 7 Jan 2025 14:04:51 +0000 Subject: [PATCH 47/57] Fix conflict --- packages/worker/src/api/controllers/global/self.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/worker/src/api/controllers/global/self.ts b/packages/worker/src/api/controllers/global/self.ts index c8d99f332c..3464bff88f 100644 --- a/packages/worker/src/api/controllers/global/self.ts +++ b/packages/worker/src/api/controllers/global/self.ts @@ -114,11 +114,7 @@ export async function getSelf(ctx: UserCtx) { const sessionAttributes = getUserSessionAttributes(ctx) // add the feature flags for this tenant -<<<<<<< HEAD const flags = await features.flags.fetch() -======= - ctx.body.flags = await features.flags.fetch() ->>>>>>> 55685be0814403644bc25d82b3218e27f6590490 ctx.body = { ...enrichedUser, From be5c619911a8c7464f0198d3b0c309f372304ddd Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:08:43 +0000 Subject: [PATCH 48/57] Add save button to user screen (#15309) * Add save button to user screen * Performance improvement * lint * Simplify code --- .../portal/users/users/[userId].svelte | 52 ++++++++++--------- .../src/api/controllers/global/users.ts | 16 +++--- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte index 57ecc9d39f..6c480d9ef8 100644 --- a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte @@ -87,6 +87,7 @@ let popover let user, tenantOwner let loaded = false + let userFieldsToUpdate = {} $: internalGroups = $groups?.filter(g => !g?.scimInfo?.isSync) @@ -164,40 +165,45 @@ return label } - async function updateUserFirstName(evt) { + async function saveUser() { try { - await users.save({ ...user, firstName: evt.target.value }) + await users.save({ ...user, ...userFieldsToUpdate }) + userFieldsToUpdate = {} await fetchUser() } catch (error) { notifications.error("Error updating user") } } + async function updateUserFirstName(evt) { + userFieldsToUpdate.firstName = evt.target.value + } + async function updateUserLastName(evt) { - try { - await users.save({ ...user, lastName: evt.target.value }) - await fetchUser() - } catch (error) { - notifications.error("Error updating user") - } + userFieldsToUpdate.lastName = evt.target.value } async function updateUserRole({ detail }) { + let flags = {} if (detail === Constants.BudibaseRoles.Developer) { - toggleFlags({ admin: { global: false }, builder: { global: true } }) + flags = { admin: { global: false }, builder: { global: true } } } else if (detail === Constants.BudibaseRoles.Admin) { - toggleFlags({ admin: { global: true }, builder: { global: true } }) + flags = { admin: { global: true }, builder: { global: true } } } else if (detail === Constants.BudibaseRoles.AppUser) { - toggleFlags({ admin: { global: false }, builder: { global: false } }) + flags = { admin: { global: false }, builder: { global: false } } } else if (detail === Constants.BudibaseRoles.Creator) { - toggleFlags({ + flags = { admin: { global: false }, builder: { global: false, creator: true, apps: user?.builder?.apps || [], }, - }) + } + } + userFieldsToUpdate = { + ...userFieldsToUpdate, + ...flags, } } @@ -209,15 +215,6 @@ tenantOwner = await users.getAccountHolder() } - async function toggleFlags(detail) { - try { - await users.save({ ...user, ...detail }) - await fetchUser() - } catch (error) { - notifications.error("Error updating user") - } - } - const addGroup = async groupId => { await groups.addUser(groupId, userId) await fetchUser() @@ -296,7 +293,7 @@
@@ -304,7 +301,7 @@
@@ -325,6 +322,13 @@ {/if} +
+ +
{#if $licensing.groupsEnabled} diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts index a028f4fd33..83f2f41b0e 100644 --- a/packages/worker/src/api/controllers/global/users.ts +++ b/packages/worker/src/api/controllers/global/users.ts @@ -72,12 +72,14 @@ export const save = async (ctx: UserCtx) => { const requestUser = ctx.request.body // Do not allow the account holder role to be changed - const accountMetadata = await users.getExistingAccounts([requestUser.email]) - if (accountMetadata?.length > 0) { - if ( - requestUser.admin?.global !== true || - requestUser.builder?.global !== true - ) { + if ( + requestUser.admin?.global !== true || + requestUser.builder?.global !== true + ) { + const accountMetadata = await users.getExistingAccounts([ + requestUser.email, + ]) + if (accountMetadata?.length > 0) { throw Error("Cannot set role of account holder") } } @@ -441,7 +443,6 @@ export const checkInvite = async (ctx: UserCtx) => { } catch (e) { console.warn("Error getting invite from code", e) ctx.throw(400, "There was a problem with the invite") - return } ctx.body = { email: invite.email, @@ -472,7 +473,6 @@ export const updateInvite = async ( invite = await cache.invite.getCode(code) } catch (e) { ctx.throw(400, "There was a problem with the invite") - return } let updated = { From d7b1b1a3671f7bab4f80cd825c4a8e98bc6cde03 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 7 Jan 2025 16:52:01 +0100 Subject: [PATCH 49/57] Fix issues when fetching view v1 data --- packages/client/src/api/patches.js | 4 ++-- packages/frontend-core/src/fetch/ViewFetch.js | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/client/src/api/patches.js b/packages/client/src/api/patches.js index 5413379b72..9203ac3c70 100644 --- a/packages/client/src/api/patches.js +++ b/packages/client/src/api/patches.js @@ -85,9 +85,9 @@ export const patchAPI = API => { } } const fetchViewData = API.fetchViewData - API.fetchViewData = async params => { + API.fetchViewData = async (viewName, params) => { const tableId = params?.tableId - const rows = await fetchViewData(params) + const rows = await fetchViewData(viewName, params) return await enrichRows(rows, tableId) } diff --git a/packages/frontend-core/src/fetch/ViewFetch.js b/packages/frontend-core/src/fetch/ViewFetch.js index 272c222dd4..eb89f9b67a 100644 --- a/packages/frontend-core/src/fetch/ViewFetch.js +++ b/packages/frontend-core/src/fetch/ViewFetch.js @@ -8,9 +8,15 @@ export default class ViewFetch extends DataFetch { async getData() { const { datasource } = this.options try { - const res = await this.API.fetchViewData(datasource.name) + const res = await this.API.fetchViewData(datasource.name, { + calculation: datasource.calculation, + field: datasource.field, + groupBy: datasource.groupBy, + tableId: datasource.tableId, + }) return { rows: res || [] } } catch (error) { + console.error(error) return { rows: [] } } } From 4d0f69556c9a8bb9bb0781fa54edb8345b32d3eb Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 7 Jan 2025 16:59:34 +0000 Subject: [PATCH 50/57] Bump version to 3.2.33 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index dde9cf03a0..3afc2c60e9 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.32", + "version": "3.2.33", "npmClient": "yarn", "concurrency": 20, "command": { From 64471bd7337ede6fbc598cd7806728858474b569 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 7 Jan 2025 17:12:56 +0000 Subject: [PATCH 51/57] Fix enrich endpoint in client --- packages/client/src/api/patches.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/client/src/api/patches.js b/packages/client/src/api/patches.js index 5413379b72..6ea3b7c183 100644 --- a/packages/client/src/api/patches.js +++ b/packages/client/src/api/patches.js @@ -66,10 +66,9 @@ export const patchAPI = API => { } } const fetchRelationshipData = API.fetchRelationshipData - API.fetchRelationshipData = async params => { - const tableId = params?.tableId - const rows = await fetchRelationshipData(params) - return await enrichRows(rows, tableId) + API.fetchRelationshipData = async (sourceId, rowId, fieldName) => { + const rows = await fetchRelationshipData(sourceId, rowId, fieldName) + return await enrichRows(rows, sourceId) } const fetchTableData = API.fetchTableData API.fetchTableData = async tableId => { From 21bfb7a45da8b1b615c100d8d52d0e991e24eae5 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 7 Jan 2025 17:47:14 +0000 Subject: [PATCH 52/57] Bump version to 3.2.34 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 3afc2c60e9..bc3f341979 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.33", + "version": "3.2.34", "npmClient": "yarn", "concurrency": 20, "command": { From 0d1c86777ca471f6e8f2131e28f127ea74aa3c03 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 8 Jan 2025 09:26:44 +0000 Subject: [PATCH 53/57] Fix usage calculations --- packages/builder/src/stores/portal/licensing.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/stores/portal/licensing.ts b/packages/builder/src/stores/portal/licensing.ts index 0b56e14005..99970313e2 100644 --- a/packages/builder/src/stores/portal/licensing.ts +++ b/packages/builder/src/stores/portal/licensing.ts @@ -227,7 +227,7 @@ class LicensingStore extends BudiStore { MonthlyQuotaName.AUTOMATIONS, ].reduce((acc: MonthlyMetrics, key) => { const limit = license.quotas.usage.monthly[key].value - const used = (usage.monthly.current?.[key] || 0 / limit) * 100 + const used = ((usage.monthly.current?.[key] || 0) / limit) * 100 acc[key] = limit > -1 ? Math.floor(used) : -1 return acc }, {}) @@ -236,7 +236,7 @@ class LicensingStore extends BudiStore { const staticMetrics = [StaticQuotaName.APPS, StaticQuotaName.ROWS].reduce( (acc: StaticMetrics, key) => { const limit = license.quotas.usage.static[key].value - const used = (usage.usageQuota[key] || 0 / limit) * 100 + const used = ((usage.usageQuota[key] || 0) / limit) * 100 acc[key] = limit > -1 ? Math.floor(used) : -1 return acc }, From aec4cc5bfbe93c494e0b9cd74b9d4779b277c476 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 8 Jan 2025 09:35:31 +0000 Subject: [PATCH 54/57] Bump version to 3.2.35 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index bc3f341979..5f61c9bb35 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.34", + "version": "3.2.35", "npmClient": "yarn", "concurrency": 20, "command": { From 377e764d5bcbe204e5cc37675242f54690dc82f4 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 8 Jan 2025 10:25:44 +0000 Subject: [PATCH 55/57] Bump version to 3.2.36 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 5f61c9bb35..9b2cacda12 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.35", + "version": "3.2.36", "npmClient": "yarn", "concurrency": 20, "command": { From 8eed6de0800524232c28d22b5bac0d57282ff6a7 Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Wed, 8 Jan 2025 10:28:08 +0000 Subject: [PATCH 56/57] Revert "Update AWS SDK to V3" --- .../__mocks__/@aws-sdk/client-s3.ts | 28 - .../@aws-sdk/s3-request-presigner.ts | 4 - packages/backend-core/__mocks__/aws-sdk.ts | 19 + packages/backend-core/package.json | 6 +- packages/backend-core/src/environment.ts | 2 +- .../src/objectStore/buckets/app.ts | 8 +- .../src/objectStore/buckets/global.ts | 8 +- .../src/objectStore/buckets/plugins.ts | 22 +- .../src/objectStore/buckets/tests/app.spec.ts | 24 +- .../objectStore/buckets/tests/global.spec.ts | 26 +- .../objectStore/buckets/tests/plugins.spec.ts | 28 +- .../src/objectStore/objectStore.ts | 198 ++- .../backend-core/src/objectStore/utils.ts | 9 +- packages/cli/src/backups/objectStore.ts | 25 +- packages/server/package.json | 5 +- .../server/src/api/controllers/application.ts | 2 +- .../src/api/controllers/static/index.ts | 26 +- .../src/api/routes/tests/static.spec.ts | 19 +- .../src/automations/tests/createRow.spec.ts | 18 +- packages/server/src/integrations/dynamodb.ts | 38 +- packages/server/src/integrations/s3.ts | 57 +- .../src/integrations/tests/aws-sdk.mock.ts | 76 ++ .../src/integrations/tests/dynamodb.spec.ts | 24 +- .../server/src/integrations/tests/s3.spec.ts | 49 +- .../server/src/integrations/utils/utils.ts | 2 +- packages/server/src/sdk/plugins/plugins.ts | 2 +- .../server/src/utilities/fileSystem/app.ts | 2 +- .../server/src/utilities/fileSystem/plugin.ts | 7 +- .../src/utilities/rowProcessor/index.ts | 14 +- .../src/api/controllers/global/configs.ts | 46 +- yarn.lock | 1107 +---------------- 31 files changed, 364 insertions(+), 1537 deletions(-) delete mode 100644 packages/backend-core/__mocks__/@aws-sdk/client-s3.ts delete mode 100644 packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts create mode 100644 packages/backend-core/__mocks__/aws-sdk.ts create mode 100644 packages/server/src/integrations/tests/aws-sdk.mock.ts diff --git a/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts b/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts deleted file mode 100644 index 8f002f41a8..0000000000 --- a/packages/backend-core/__mocks__/@aws-sdk/client-s3.ts +++ /dev/null @@ -1,28 +0,0 @@ -export class S3 { - headBucket() { - return jest.fn().mockReturnThis() - } - deleteObject() { - return jest.fn().mockReturnThis() - } - deleteObjects() { - return jest.fn().mockReturnThis() - } - createBucket() { - return jest.fn().mockReturnThis() - } - getObject() { - return jest.fn().mockReturnThis() - } - listObject() { - return jest.fn().mockReturnThis() - } - promise() { - return jest.fn().mockReturnThis() - } - catch() { - return jest.fn() - } -} - -export const GetObjectCommand = jest.fn(inputs => ({ inputs })) diff --git a/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts b/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts deleted file mode 100644 index 3ed2c10595..0000000000 --- a/packages/backend-core/__mocks__/@aws-sdk/s3-request-presigner.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const getSignedUrl = jest.fn((_, cmd) => { - const { inputs } = cmd - return `http://s3.example.com/${inputs?.Bucket}/${inputs?.Key}` -}) diff --git a/packages/backend-core/__mocks__/aws-sdk.ts b/packages/backend-core/__mocks__/aws-sdk.ts new file mode 100644 index 0000000000..e3be511d08 --- /dev/null +++ b/packages/backend-core/__mocks__/aws-sdk.ts @@ -0,0 +1,19 @@ +const mockS3 = { + headBucket: jest.fn().mockReturnThis(), + deleteObject: jest.fn().mockReturnThis(), + deleteObjects: jest.fn().mockReturnThis(), + createBucket: jest.fn().mockReturnThis(), + getObject: jest.fn().mockReturnThis(), + listObject: jest.fn().mockReturnThis(), + getSignedUrl: jest.fn((operation: string, params: any) => { + return `http://s3.example.com/${params.Bucket}/${params.Key}` + }), + promise: jest.fn().mockReturnThis(), + catch: jest.fn(), +} + +const AWS = { + S3: jest.fn(() => mockS3), +} + +export default AWS diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index b380fca017..3e1b5f324b 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -30,9 +30,6 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@aws-sdk/client-s3": "3.709.0", - "@aws-sdk/lib-storage": "3.709.0", - "@aws-sdk/s3-request-presigner": "3.709.0", "@budibase/nano": "10.1.5", "@budibase/pouchdb-replication-stream": "1.2.11", "@budibase/shared-core": "*", @@ -74,13 +71,11 @@ "devDependencies": { "@jest/types": "^29.6.3", "@shopify/jest-koa-mocks": "5.1.1", - "@smithy/types": "4.0.0", "@swc/core": "1.3.71", "@swc/jest": "0.2.27", "@types/chance": "1.1.3", "@types/cookies": "0.7.8", "@types/jest": "29.5.5", - "@types/koa": "2.13.4", "@types/lodash": "4.14.200", "@types/node-fetch": "2.6.4", "@types/pouchdb": "6.4.2", @@ -88,6 +83,7 @@ "@types/semver": "7.3.7", "@types/tar-fs": "2.0.1", "@types/uuid": "8.3.4", + "@types/koa": "2.13.4", "chance": "1.1.8", "ioredis-mock": "8.9.0", "jest": "29.7.0", diff --git a/packages/backend-core/src/environment.ts b/packages/backend-core/src/environment.ts index 9a46758062..954fdd4135 100644 --- a/packages/backend-core/src/environment.ts +++ b/packages/backend-core/src/environment.ts @@ -154,7 +154,7 @@ const environment = { MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY, MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY, AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN, - AWS_REGION: process.env.AWS_REGION || "eu-west-1", + AWS_REGION: process.env.AWS_REGION, MINIO_URL: process.env.MINIO_URL, MINIO_ENABLED: process.env.MINIO_ENABLED || 1, INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, diff --git a/packages/backend-core/src/objectStore/buckets/app.ts b/packages/backend-core/src/objectStore/buckets/app.ts index dbf49ca994..43bc965c65 100644 --- a/packages/backend-core/src/objectStore/buckets/app.ts +++ b/packages/backend-core/src/objectStore/buckets/app.ts @@ -13,7 +13,7 @@ export function clientLibraryPath(appId: string) { * due to issues with the domain we were unable to continue doing this - keeping * incase we are able to switch back to CDN path again in future. */ -export async function clientLibraryCDNUrl(appId: string, version: string) { +export function clientLibraryCDNUrl(appId: string, version: string) { let file = clientLibraryPath(appId) if (env.CLOUDFRONT_CDN) { // append app version to bust the cache @@ -24,7 +24,7 @@ export async function clientLibraryCDNUrl(appId: string, version: string) { // file is public return cloudfront.getUrl(file) } else { - return await objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) + return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) } } @@ -44,10 +44,10 @@ export function clientLibraryUrl(appId: string, version: string) { return `/api/assets/client?${qs.encode(qsParams)}` } -export async function getAppFileUrl(s3Key: string) { +export function getAppFileUrl(s3Key: string) { if (env.CLOUDFRONT_CDN) { return cloudfront.getPresignedUrl(s3Key) } else { - return await objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key) + return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key) } } diff --git a/packages/backend-core/src/objectStore/buckets/global.ts b/packages/backend-core/src/objectStore/buckets/global.ts index 29c3347b05..69e201bb98 100644 --- a/packages/backend-core/src/objectStore/buckets/global.ts +++ b/packages/backend-core/src/objectStore/buckets/global.ts @@ -5,11 +5,7 @@ import * as cloudfront from "../cloudfront" // URLs -export const getGlobalFileUrl = async ( - type: string, - name: string, - etag?: string -) => { +export const getGlobalFileUrl = (type: string, name: string, etag?: string) => { let file = getGlobalFileS3Key(type, name) if (env.CLOUDFRONT_CDN) { if (etag) { @@ -17,7 +13,7 @@ export const getGlobalFileUrl = async ( } return cloudfront.getPresignedUrl(file) } else { - return await objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file) + return objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file) } } diff --git a/packages/backend-core/src/objectStore/buckets/plugins.ts b/packages/backend-core/src/objectStore/buckets/plugins.ts index 131f180f48..02be9345ab 100644 --- a/packages/backend-core/src/objectStore/buckets/plugins.ts +++ b/packages/backend-core/src/objectStore/buckets/plugins.ts @@ -6,25 +6,23 @@ import { Plugin } from "@budibase/types" // URLS -export async function enrichPluginURLs(plugins?: Plugin[]): Promise { +export function enrichPluginURLs(plugins?: Plugin[]): Plugin[] { if (!plugins || !plugins.length) { return [] } - return await Promise.all( - plugins.map(async plugin => { - const jsUrl = await getPluginJSUrl(plugin) - const iconUrl = await getPluginIconUrl(plugin) - return { ...plugin, jsUrl, iconUrl } - }) - ) + return plugins.map(plugin => { + const jsUrl = getPluginJSUrl(plugin) + const iconUrl = getPluginIconUrl(plugin) + return { ...plugin, jsUrl, iconUrl } + }) } -async function getPluginJSUrl(plugin: Plugin) { +function getPluginJSUrl(plugin: Plugin) { const s3Key = getPluginJSKey(plugin) return getPluginUrl(s3Key) } -async function getPluginIconUrl(plugin: Plugin) { +function getPluginIconUrl(plugin: Plugin): string | undefined { const s3Key = getPluginIconKey(plugin) if (!s3Key) { return @@ -32,11 +30,11 @@ async function getPluginIconUrl(plugin: Plugin) { return getPluginUrl(s3Key) } -async function getPluginUrl(s3Key: string) { +function getPluginUrl(s3Key: string) { if (env.CLOUDFRONT_CDN) { return cloudfront.getPresignedUrl(s3Key) } else { - return await objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key) + return objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key) } } diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index e36b36d39d..4a132ce54d 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -93,25 +93,25 @@ describe("app", () => { testEnv.multiTenant() }) - it("gets url with embedded minio", async () => { + it("gets url with embedded minio", () => { testEnv.withMinio() - const url = await getAppFileUrl() + const url = getAppFileUrl() expect(url).toBe( "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" ) }) - it("gets url with custom S3", async () => { + it("gets url with custom S3", () => { testEnv.withS3() - const url = await getAppFileUrl() + const url = getAppFileUrl() expect(url).toBe( "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" ) }) - it("gets url with cloudfront + s3", async () => { + it("gets url with cloudfront + s3", () => { testEnv.withCloudfront() - const url = await getAppFileUrl() + const url = getAppFileUrl() // omit rest of signed params expect( url.includes("http://cf.example.com/app_123/attachments/image.jpeg?") @@ -126,8 +126,8 @@ describe("app", () => { it("gets url with embedded minio", async () => { testEnv.withMinio() - await testEnv.withTenant(async () => { - const url = await getAppFileUrl() + await testEnv.withTenant(() => { + const url = getAppFileUrl() expect(url).toBe( "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" ) @@ -136,8 +136,8 @@ describe("app", () => { it("gets url with custom S3", async () => { testEnv.withS3() - await testEnv.withTenant(async () => { - const url = await getAppFileUrl() + await testEnv.withTenant(() => { + const url = getAppFileUrl() expect(url).toBe( "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" ) @@ -146,8 +146,8 @@ describe("app", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(async () => { - const url = await getAppFileUrl() + await testEnv.withTenant(() => { + const url = getAppFileUrl() // omit rest of signed params expect( url.includes( diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index c98d98e016..148a4c80bf 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -3,7 +3,7 @@ import { testEnv } from "../../../../tests/extra" describe("global", () => { describe("getGlobalFileUrl", () => { - async function getGlobalFileUrl() { + function getGlobalFileUrl() { return global.getGlobalFileUrl("settings", "logoUrl", "etag") } @@ -12,21 +12,21 @@ describe("global", () => { testEnv.singleTenant() }) - it("gets url with embedded minio", async () => { + it("gets url with embedded minio", () => { testEnv.withMinio() - const url = await getGlobalFileUrl() + const url = getGlobalFileUrl() expect(url).toBe("/files/signed/global/settings/logoUrl") }) - it("gets url with custom S3", async () => { + it("gets url with custom S3", () => { testEnv.withS3() - const url = await getGlobalFileUrl() + const url = getGlobalFileUrl() expect(url).toBe("http://s3.example.com/global/settings/logoUrl") }) - it("gets url with cloudfront + s3", async () => { + it("gets url with cloudfront + s3", () => { testEnv.withCloudfront() - const url = await getGlobalFileUrl() + const url = getGlobalFileUrl() // omit rest of signed params expect( url.includes("http://cf.example.com/settings/logoUrl?etag=etag&") @@ -41,16 +41,16 @@ describe("global", () => { it("gets url with embedded minio", async () => { testEnv.withMinio() - await testEnv.withTenant(async tenantId => { - const url = await getGlobalFileUrl() + await testEnv.withTenant(tenantId => { + const url = getGlobalFileUrl() expect(url).toBe(`/files/signed/global/${tenantId}/settings/logoUrl`) }) }) it("gets url with custom S3", async () => { testEnv.withS3() - await testEnv.withTenant(async tenantId => { - const url = await getGlobalFileUrl() + await testEnv.withTenant(tenantId => { + const url = getGlobalFileUrl() expect(url).toBe( `http://s3.example.com/global/${tenantId}/settings/logoUrl` ) @@ -59,8 +59,8 @@ describe("global", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(async tenantId => { - const url = await getGlobalFileUrl() + await testEnv.withTenant(tenantId => { + const url = getGlobalFileUrl() // omit rest of signed params expect( url.includes( diff --git a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts index 0906ea91c2..fc2822314e 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts @@ -6,8 +6,8 @@ describe("plugins", () => { describe("enrichPluginURLs", () => { const plugin = structures.plugins.plugin() - async function getEnrichedPluginUrls() { - const enriched = (await plugins.enrichPluginURLs([plugin]))[0] + function getEnrichedPluginUrls() { + const enriched = plugins.enrichPluginURLs([plugin])[0] return { jsUrl: enriched.jsUrl!, iconUrl: enriched.iconUrl!, @@ -19,9 +19,9 @@ describe("plugins", () => { testEnv.singleTenant() }) - it("gets url with embedded minio", async () => { + it("gets url with embedded minio", () => { testEnv.withMinio() - const urls = await getEnrichedPluginUrls() + const urls = getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `/files/signed/plugins/${plugin.name}/plugin.min.js` ) @@ -30,9 +30,9 @@ describe("plugins", () => { ) }) - it("gets url with custom S3", async () => { + it("gets url with custom S3", () => { testEnv.withS3() - const urls = await getEnrichedPluginUrls() + const urls = getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `http://s3.example.com/plugins/${plugin.name}/plugin.min.js` ) @@ -41,9 +41,9 @@ describe("plugins", () => { ) }) - it("gets url with cloudfront + s3", async () => { + it("gets url with cloudfront + s3", () => { testEnv.withCloudfront() - const urls = await getEnrichedPluginUrls() + const urls = getEnrichedPluginUrls() // omit rest of signed params expect( urls.jsUrl.includes( @@ -65,8 +65,8 @@ describe("plugins", () => { it("gets url with embedded minio", async () => { testEnv.withMinio() - await testEnv.withTenant(async tenantId => { - const urls = await getEnrichedPluginUrls() + await testEnv.withTenant(tenantId => { + const urls = getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `/files/signed/plugins/${tenantId}/${plugin.name}/plugin.min.js` ) @@ -78,8 +78,8 @@ describe("plugins", () => { it("gets url with custom S3", async () => { testEnv.withS3() - await testEnv.withTenant(async tenantId => { - const urls = await getEnrichedPluginUrls() + await testEnv.withTenant(tenantId => { + const urls = getEnrichedPluginUrls() expect(urls.jsUrl).toBe( `http://s3.example.com/plugins/${tenantId}/${plugin.name}/plugin.min.js` ) @@ -91,8 +91,8 @@ describe("plugins", () => { it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() - await testEnv.withTenant(async tenantId => { - const urls = await getEnrichedPluginUrls() + await testEnv.withTenant(tenantId => { + const urls = getEnrichedPluginUrls() // omit rest of signed params expect( urls.jsUrl.includes( diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 4f07abe7e2..79875b5e99 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -1,15 +1,6 @@ const sanitize = require("sanitize-s3-objectkey") -import { - HeadObjectCommandOutput, - PutObjectCommandInput, - S3, - S3ClientConfig, - GetObjectCommand, - _Object as S3Object, -} from "@aws-sdk/client-s3" -import { Upload } from "@aws-sdk/lib-storage" -import { getSignedUrl } from "@aws-sdk/s3-request-presigner" +import AWS from "aws-sdk" import stream, { Readable } from "stream" import fetch from "node-fetch" import tar from "tar-fs" @@ -22,8 +13,8 @@ import { bucketTTLConfig, budibaseTempDir } from "./utils" import { v4 } from "uuid" import { APP_PREFIX, APP_DEV_PREFIX } from "../db" import fsp from "fs/promises" +import { HeadObjectOutput } from "aws-sdk/clients/s3" import { ReadableStream } from "stream/web" -import { NodeJsRuntimeStreamingBlobPayloadOutputTypes } from "@smithy/types" const streamPipeline = promisify(stream.pipeline) // use this as a temporary store of buckets that are being created @@ -93,24 +84,26 @@ export function sanitizeBucket(input: string) { * @constructor */ export function ObjectStore( + bucket: string, opts: { presigning: boolean } = { presigning: false } ) { - const config: S3ClientConfig = { - forcePathStyle: true, - credentials: { - accessKeyId: env.MINIO_ACCESS_KEY!, - secretAccessKey: env.MINIO_SECRET_KEY!, - }, + const config: AWS.S3.ClientConfiguration = { + s3ForcePathStyle: true, + signatureVersion: "v4", + apiVersion: "2006-03-01", + accessKeyId: env.MINIO_ACCESS_KEY, + secretAccessKey: env.MINIO_SECRET_KEY, region: env.AWS_REGION, } + if (bucket) { + config.params = { + Bucket: sanitizeBucket(bucket), + } + } // for AWS Credentials using temporary session token if (!env.MINIO_ENABLED && env.AWS_SESSION_TOKEN) { - config.credentials = { - accessKeyId: env.MINIO_ACCESS_KEY!, - secretAccessKey: env.MINIO_SECRET_KEY!, - sessionToken: env.AWS_SESSION_TOKEN, - } + config.sessionToken = env.AWS_SESSION_TOKEN } // custom S3 is in use i.e. minio @@ -120,13 +113,13 @@ export function ObjectStore( // Normally a signed url will need to be generated with a specified host in mind. // To support dynamic hosts, e.g. some unknown self-hosted installation url, // use a predefined host. The host 'minio-service' is also forwarded to minio requests via nginx - config.endpoint = "http://minio-service" + config.endpoint = "minio-service" } else { config.endpoint = env.MINIO_URL } } - return new S3(config) + return new AWS.S3(config) } /** @@ -139,25 +132,26 @@ export async function createBucketIfNotExists( ): Promise<{ created: boolean; exists: boolean }> { bucketName = sanitizeBucket(bucketName) try { - await client.headBucket({ - Bucket: bucketName, - }) + await client + .headBucket({ + Bucket: bucketName, + }) + .promise() return { created: false, exists: true } } catch (err: any) { - const statusCode = err.statusCode || err.$response?.statusCode - const promises: Record | undefined> = - STATE.bucketCreationPromises - const doesntExist = statusCode === 404, - noAccess = statusCode === 403 + const promises: any = STATE.bucketCreationPromises + const doesntExist = err.statusCode === 404, + noAccess = err.statusCode === 403 if (promises[bucketName]) { await promises[bucketName] return { created: false, exists: true } } else if (doesntExist || noAccess) { if (doesntExist) { - promises[bucketName] = client.createBucket({ - Bucket: bucketName, - }) - + promises[bucketName] = client + .createBucket({ + Bucket: bucketName, + }) + .promise() await promises[bucketName] delete promises[bucketName] return { created: true, exists: false } @@ -186,26 +180,25 @@ export async function upload({ const fileBytes = path ? (await fsp.open(path)).createReadStream() : body - const objectStore = ObjectStore() + const objectStore = ObjectStore(bucketName) const bucketCreated = await createBucketIfNotExists(objectStore, bucketName) if (ttl && bucketCreated.created) { let ttlConfig = bucketTTLConfig(bucketName, ttl) - await objectStore.putBucketLifecycleConfiguration(ttlConfig) + await objectStore.putBucketLifecycleConfiguration(ttlConfig).promise() } let contentType = type - const finalContentType = contentType - ? contentType - : extension - ? CONTENT_TYPE_MAP[extension.toLowerCase()] - : CONTENT_TYPE_MAP.txt - const config: PutObjectCommandInput = { + if (!contentType) { + contentType = extension + ? CONTENT_TYPE_MAP[extension.toLowerCase()] + : CONTENT_TYPE_MAP.txt + } + const config: any = { // windows file paths need to be converted to forward slashes for s3 - Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filename), - Body: fileBytes as stream.Readable | Buffer, - ContentType: finalContentType, + Body: fileBytes, + ContentType: contentType, } if (metadata && typeof metadata === "object") { // remove any nullish keys from the metadata object, as these may be considered invalid @@ -214,15 +207,10 @@ export async function upload({ delete metadata[key] } } - config.Metadata = metadata as Record + config.Metadata = metadata } - const upload = new Upload({ - client: objectStore, - params: config, - }) - - return upload.done() + return objectStore.upload(config).promise() } /** @@ -241,12 +229,12 @@ export async function streamUpload({ throw new Error("Stream to upload is invalid/undefined") } const extension = filename.split(".").pop() - const objectStore = ObjectStore() + const objectStore = ObjectStore(bucketName) const bucketCreated = await createBucketIfNotExists(objectStore, bucketName) if (ttl && bucketCreated.created) { let ttlConfig = bucketTTLConfig(bucketName, ttl) - await objectStore.putBucketLifecycleConfiguration(ttlConfig) + await objectStore.putBucketLifecycleConfiguration(ttlConfig).promise() } // Set content type for certain known extensions @@ -279,15 +267,13 @@ export async function streamUpload({ ...extra, } - const upload = new Upload({ - client: objectStore, - params, - }) - const details = await upload.done() - const headDetails = await objectStore.headObject({ - Bucket: bucket, - Key: objKey, - }) + const details = await objectStore.upload(params).promise() + const headDetails = await objectStore + .headObject({ + Bucket: bucket, + Key: objKey, + }) + .promise() return { ...details, ContentLength: headDetails.ContentLength, @@ -298,44 +284,35 @@ export async function streamUpload({ * retrieves the contents of a file from the object store, if it is a known content type it * will be converted, otherwise it will be returned as a buffer stream. */ -export async function retrieve( - bucketName: string, - filepath: string -): Promise { - const objectStore = ObjectStore() +export async function retrieve(bucketName: string, filepath: string) { + const objectStore = ObjectStore(bucketName) const params = { Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filepath), } - const response = await objectStore.getObject(params) - if (!response.Body) { - throw new Error("Unable to retrieve object") - } - const nodeResponse = - response.Body as NodeJsRuntimeStreamingBlobPayloadOutputTypes + const response: any = await objectStore.getObject(params).promise() // currently these are all strings if (STRING_CONTENT_TYPES.includes(response.ContentType)) { - return nodeResponse.toString() + return response.Body.toString("utf8") } else { - return nodeResponse + return response.Body } } -export async function listAllObjects( - bucketName: string, - path: string -): Promise { - const objectStore = ObjectStore() +export async function listAllObjects(bucketName: string, path: string) { + const objectStore = ObjectStore(bucketName) const list = (params: ListParams = {}) => { - return objectStore.listObjectsV2({ - ...params, - Bucket: sanitizeBucket(bucketName), - Prefix: sanitizeKey(path), - }) + return objectStore + .listObjectsV2({ + ...params, + Bucket: sanitizeBucket(bucketName), + Prefix: sanitizeKey(path), + }) + .promise() } let isTruncated = false, token, - objects: Object[] = [] + objects: AWS.S3.Types.Object[] = [] do { let params: ListParams = {} if (token) { @@ -354,19 +331,18 @@ export async function listAllObjects( /** * Generate a presigned url with a default TTL of 1 hour */ -export async function getPresignedUrl( +export function getPresignedUrl( bucketName: string, key: string, durationSeconds = 3600 ) { - const objectStore = ObjectStore({ presigning: true }) + const objectStore = ObjectStore(bucketName, { presigning: true }) const params = { Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(key), + Expires: durationSeconds, } - const url = await getSignedUrl(objectStore, new GetObjectCommand(params), { - expiresIn: durationSeconds, - }) + const url = objectStore.getSignedUrl("getObject", params) if (!env.MINIO_ENABLED) { // return the full URL to the client @@ -390,11 +366,7 @@ export async function retrieveToTmp(bucketName: string, filepath: string) { filepath = sanitizeKey(filepath) const data = await retrieve(bucketName, filepath) const outputPath = join(budibaseTempDir(), v4()) - if (data instanceof stream.Readable) { - data.pipe(fs.createWriteStream(outputPath)) - } else { - fs.writeFileSync(outputPath, data) - } + fs.writeFileSync(outputPath, data) return outputPath } @@ -436,17 +408,17 @@ export async function retrieveDirectory(bucketName: string, path: string) { * Delete a single file. */ export async function deleteFile(bucketName: string, filepath: string) { - const objectStore = ObjectStore() + const objectStore = ObjectStore(bucketName) await createBucketIfNotExists(objectStore, bucketName) const params = { Bucket: bucketName, Key: sanitizeKey(filepath), } - return objectStore.deleteObject(params) + return objectStore.deleteObject(params).promise() } export async function deleteFiles(bucketName: string, filepaths: string[]) { - const objectStore = ObjectStore() + const objectStore = ObjectStore(bucketName) await createBucketIfNotExists(objectStore, bucketName) const params = { Bucket: bucketName, @@ -454,7 +426,7 @@ export async function deleteFiles(bucketName: string, filepaths: string[]) { Objects: filepaths.map((path: any) => ({ Key: sanitizeKey(path) })), }, } - return objectStore.deleteObjects(params) + return objectStore.deleteObjects(params).promise() } /** @@ -466,13 +438,13 @@ export async function deleteFolder( ): Promise { bucketName = sanitizeBucket(bucketName) folder = sanitizeKey(folder) - const client = ObjectStore() + const client = ObjectStore(bucketName) const listParams = { Bucket: bucketName, Prefix: folder, } - const existingObjectsResponse = await client.listObjects(listParams) + const existingObjectsResponse = await client.listObjects(listParams).promise() if (existingObjectsResponse.Contents?.length === 0) { return } @@ -487,7 +459,7 @@ export async function deleteFolder( deleteParams.Delete.Objects.push({ Key: content.Key }) }) - const deleteResponse = await client.deleteObjects(deleteParams) + const deleteResponse = await client.deleteObjects(deleteParams).promise() // can only empty 1000 items at once if (deleteResponse.Deleted?.length === 1000) { return deleteFolder(bucketName, folder) @@ -562,33 +534,29 @@ export async function getReadStream( ): Promise { bucketName = sanitizeBucket(bucketName) path = sanitizeKey(path) - const client = ObjectStore() + const client = ObjectStore(bucketName) const params = { Bucket: bucketName, Key: path, } - const response = await client.getObject(params) - if (!response.Body || !(response.Body instanceof stream.Readable)) { - throw new Error("Unable to retrieve stream - invalid response") - } - return response.Body + return client.getObject(params).createReadStream() } export async function getObjectMetadata( bucket: string, path: string -): Promise { +): Promise { bucket = sanitizeBucket(bucket) path = sanitizeKey(path) - const client = ObjectStore() + const client = ObjectStore(bucket) const params = { Bucket: bucket, Key: path, } try { - return await client.headObject(params) + return await client.headObject(params).promise() } catch (err: any) { throw new Error("Unable to retrieve metadata from object") } diff --git a/packages/backend-core/src/objectStore/utils.ts b/packages/backend-core/src/objectStore/utils.ts index 2a9dd26e02..30c2fefbf1 100644 --- a/packages/backend-core/src/objectStore/utils.ts +++ b/packages/backend-core/src/objectStore/utils.ts @@ -2,10 +2,7 @@ import path, { join } from "path" import { tmpdir } from "os" import fs from "fs" import env from "../environment" -import { - LifecycleRule, - PutBucketLifecycleConfigurationCommandInput, -} from "@aws-sdk/client-s3" +import { PutBucketLifecycleConfigurationRequest } from "aws-sdk/clients/s3" import * as objectStore from "./objectStore" import { AutomationAttachment, @@ -46,8 +43,8 @@ export function budibaseTempDir() { export const bucketTTLConfig = ( bucketName: string, days: number -): PutBucketLifecycleConfigurationCommandInput => { - const lifecycleRule: LifecycleRule = { +): PutBucketLifecycleConfigurationRequest => { + const lifecycleRule = { ID: `${bucketName}-ExpireAfter${days}days`, Prefix: "", Status: "Enabled", diff --git a/packages/cli/src/backups/objectStore.ts b/packages/cli/src/backups/objectStore.ts index 34e231b87b..2a24199603 100644 --- a/packages/cli/src/backups/objectStore.ts +++ b/packages/cli/src/backups/objectStore.ts @@ -3,7 +3,6 @@ import fs from "fs" import { join } from "path" import { TEMP_DIR, MINIO_DIR } from "./utils" import { progressBar } from "../utils" -import * as stream from "node:stream" const { ObjectStoreBuckets, @@ -21,21 +20,15 @@ export async function exportObjects() { let fullList: any[] = [] let errorCount = 0 for (let bucket of bucketList) { - const client = ObjectStore() + const client = ObjectStore(bucket) try { - await client.headBucket({ - Bucket: bucket, - }) + await client.headBucket().promise() } catch (err) { errorCount++ continue } - const list = await client.listObjectsV2({ - Bucket: bucket, - }) - fullList = fullList.concat( - list.Contents?.map(el => ({ ...el, bucket })) || [] - ) + const list = (await client.listObjectsV2().promise()) as { Contents: any[] } + fullList = fullList.concat(list.Contents.map(el => ({ ...el, bucket }))) } if (errorCount === bucketList.length) { throw new Error("Unable to access MinIO/S3 - check environment config.") @@ -50,13 +43,7 @@ export async function exportObjects() { const dirs = possiblePath.slice(0, possiblePath.length - 1) fs.mkdirSync(join(path, object.bucket, ...dirs), { recursive: true }) } - if (data instanceof stream.Readable) { - data.pipe( - fs.createWriteStream(join(path, object.bucket, ...possiblePath)) - ) - } else { - fs.writeFileSync(join(path, object.bucket, ...possiblePath), data) - } + fs.writeFileSync(join(path, object.bucket, ...possiblePath), data) bar.update(++count) } bar.stop() @@ -73,7 +60,7 @@ export async function importObjects() { const bar = progressBar(total) let count = 0 for (let bucket of buckets) { - const client = ObjectStore() + const client = ObjectStore(bucket) await createBucketIfNotExists(client, bucket) const files = await uploadDirectory(bucket, join(path, bucket), "/") count += files.length diff --git a/packages/server/package.json b/packages/server/package.json index fd448629e8..8cd49a0fe8 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -50,10 +50,6 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@aws-sdk/client-dynamodb": "3.709.0", - "@aws-sdk/client-s3": "3.709.0", - "@aws-sdk/lib-dynamodb": "3.709.0", - "@aws-sdk/s3-request-presigner": "3.709.0", "@azure/msal-node": "^2.5.1", "@budibase/backend-core": "*", "@budibase/client": "*", @@ -74,6 +70,7 @@ "airtable": "0.12.2", "arangojs": "7.2.0", "archiver": "7.0.1", + "aws-sdk": "2.1692.0", "bcrypt": "5.1.0", "bcryptjs": "2.4.3", "bson": "^6.9.0", diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index 7ffd075ec0..4169087a63 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -230,7 +230,7 @@ export async function fetchAppPackage( const license = await licensing.cache.getCachedLicense() // Enrich plugin URLs - application.usedPlugins = await objectStore.enrichPluginURLs( + application.usedPlugins = objectStore.enrichPluginURLs( application.usedPlugins ) diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts index 8b5c61e875..0dd5e77c50 100644 --- a/packages/server/src/api/controllers/static/index.ts +++ b/packages/server/src/api/controllers/static/index.ts @@ -18,8 +18,7 @@ import { objectStore, utils, } from "@budibase/backend-core" -import { getSignedUrl } from "@aws-sdk/s3-request-presigner" -import { PutObjectCommand, S3 } from "@aws-sdk/client-s3" +import AWS from "aws-sdk" import fs from "fs" import sdk from "../../../sdk" import * as pro from "@budibase/pro" @@ -129,9 +128,9 @@ export const uploadFile = async function ( return { size: file.size, name: file.name, - url: await objectStore.getAppFileUrl(s3Key), + url: objectStore.getAppFileUrl(s3Key), extension, - key: response.Key!, + key: response.Key, } }) ) @@ -211,11 +210,11 @@ export const serveApp = async function (ctx: UserCtx) { usedPlugins: plugins, favicon: branding.faviconUrl !== "" - ? await objectStore.getGlobalFileUrl("settings", "faviconUrl") + ? objectStore.getGlobalFileUrl("settings", "faviconUrl") : "", logo: config?.logoUrl !== "" - ? await objectStore.getGlobalFileUrl("settings", "logoUrl") + ? objectStore.getGlobalFileUrl("settings", "logoUrl") : "", appMigrating: needMigrations, nonce: ctx.state.nonce, @@ -244,7 +243,7 @@ export const serveApp = async function (ctx: UserCtx) { metaDescription: branding?.metaDescription || "", favicon: branding.faviconUrl !== "" - ? await objectStore.getGlobalFileUrl("settings", "faviconUrl") + ? objectStore.getGlobalFileUrl("settings", "faviconUrl") : "", }) @@ -335,17 +334,16 @@ export const getSignedUploadURL = async function ( ctx.throw(400, "bucket and key values are required") } try { - const s3 = new S3({ + const s3 = new AWS.S3({ region: awsRegion, endpoint: datasource?.config?.endpoint || undefined, - - credentials: { - accessKeyId: datasource?.config?.accessKeyId as string, - secretAccessKey: datasource?.config?.secretAccessKey as string, - }, + accessKeyId: datasource?.config?.accessKeyId as string, + secretAccessKey: datasource?.config?.secretAccessKey as string, + apiVersion: "2006-03-01", + signatureVersion: "v4", }) const params = { Bucket: bucket, Key: key } - signedUrl = await getSignedUrl(s3, new PutObjectCommand(params)) + signedUrl = s3.getSignedUrl("putObject", params) if (datasource?.config?.endpoint) { publicUrl = `${datasource.config.endpoint}/${bucket}/${key}` } else { diff --git a/packages/server/src/api/routes/tests/static.spec.ts b/packages/server/src/api/routes/tests/static.spec.ts index 872085c382..c2808603e9 100644 --- a/packages/server/src/api/routes/tests/static.spec.ts +++ b/packages/server/src/api/routes/tests/static.spec.ts @@ -1,10 +1,12 @@ // Directly mock the AWS SDK -jest.mock("@aws-sdk/s3-request-presigner", () => ({ - getSignedUrl: jest.fn(() => { - return `http://example.com` - }), +jest.mock("aws-sdk", () => ({ + S3: jest.fn(() => ({ + getSignedUrl: jest.fn( + (operation, params) => `http://example.com/${params.Bucket}/${params.Key}` + ), + upload: jest.fn(() => ({ Contents: {} })), + })), })) -jest.mock("@aws-sdk/client-s3") import { Datasource, SourceName } from "@budibase/types" import { setEnv } from "../../../environment" @@ -75,10 +77,7 @@ describe("/static", () => { type: "datasource", name: "Test", source: SourceName.S3, - config: { - accessKeyId: "bb", - secretAccessKey: "bb", - }, + config: {}, }, }) }) @@ -92,7 +91,7 @@ describe("/static", () => { .set(config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - expect(res.body.signedUrl).toEqual("http://example.com") + expect(res.body.signedUrl).toEqual("http://example.com/foo/bar") expect(res.body.publicUrl).toEqual( `https://${bucket}.s3.eu-west-1.amazonaws.com/${key}` ) diff --git a/packages/server/src/automations/tests/createRow.spec.ts b/packages/server/src/automations/tests/createRow.spec.ts index 42b69324e2..bd78de2217 100644 --- a/packages/server/src/automations/tests/createRow.spec.ts +++ b/packages/server/src/automations/tests/createRow.spec.ts @@ -154,12 +154,11 @@ describe("test the create row action", () => { expect(result.steps[1].outputs.row.file_attachment[0]).toHaveProperty("key") let s3Key = result.steps[1].outputs.row.file_attachment[0].key - const client = objectStore.ObjectStore() + const client = objectStore.ObjectStore(objectStore.ObjectStoreBuckets.APPS) - const objectData = await client.headObject({ - Bucket: objectStore.ObjectStoreBuckets.APPS, - Key: s3Key, - }) + const objectData = await client + .headObject({ Bucket: objectStore.ObjectStoreBuckets.APPS, Key: s3Key }) + .promise() expect(objectData).toBeDefined() expect(objectData.ContentLength).toBeGreaterThan(0) @@ -230,12 +229,11 @@ describe("test the create row action", () => { ) let s3Key = result.steps[1].outputs.row.single_file_attachment.key - const client = objectStore.ObjectStore() + const client = objectStore.ObjectStore(objectStore.ObjectStoreBuckets.APPS) - const objectData = await client.headObject({ - Bucket: objectStore.ObjectStoreBuckets.APPS, - Key: s3Key, - }) + const objectData = await client + .headObject({ Bucket: objectStore.ObjectStoreBuckets.APPS, Key: s3Key }) + .promise() expect(objectData).toBeDefined() expect(objectData.ContentLength).toBeGreaterThan(0) diff --git a/packages/server/src/integrations/dynamodb.ts b/packages/server/src/integrations/dynamodb.ts index 96941ebb0e..424a3dfce0 100644 --- a/packages/server/src/integrations/dynamodb.ts +++ b/packages/server/src/integrations/dynamodb.ts @@ -7,15 +7,9 @@ import { ConnectionInfo, } from "@budibase/types" -import { - DynamoDBDocument, - PutCommandInput, - GetCommandInput, - UpdateCommandInput, - DeleteCommandInput, -} from "@aws-sdk/lib-dynamodb" -import { DynamoDB } from "@aws-sdk/client-dynamodb" +import AWS from "aws-sdk" import { AWS_REGION } from "../constants" +import { DocumentClient } from "aws-sdk/clients/dynamodb" interface DynamoDBConfig { region: string @@ -157,7 +151,7 @@ class DynamoDBIntegration implements IntegrationBase { region: config.region || AWS_REGION, endpoint: config.endpoint || undefined, } - this.client = DynamoDBDocument.from(new DynamoDB(this.config)) + this.client = new AWS.DynamoDB.DocumentClient(this.config) } async testConnection() { @@ -165,8 +159,8 @@ class DynamoDBIntegration implements IntegrationBase { connected: false, } try { - const scanRes = await new DynamoDB(this.config).listTables() - response.connected = !!scanRes.$metadata + const scanRes = await new AWS.DynamoDB(this.config).listTables().promise() + response.connected = !!scanRes.$response } catch (e: any) { response.error = e.message as string } @@ -175,13 +169,13 @@ class DynamoDBIntegration implements IntegrationBase { async create(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.put(params) + return this.client.put(params).promise() } async read(query: { table: string; json: object; index: null | string }) { @@ -190,7 +184,7 @@ class DynamoDBIntegration implements IntegrationBase { IndexName: query.index ? query.index : undefined, ...query.json, } - const response = await this.client.query(params) + const response = await this.client.query(params).promise() if (response.Items) { return response.Items } @@ -203,7 +197,7 @@ class DynamoDBIntegration implements IntegrationBase { IndexName: query.index ? query.index : undefined, ...query.json, } - const response = await this.client.scan(params) + const response = await this.client.scan(params).promise() if (response.Items) { return response.Items } @@ -214,40 +208,40 @@ class DynamoDBIntegration implements IntegrationBase { const params = { TableName: query.table, } - return new DynamoDB(this.config).describeTable(params) + return new AWS.DynamoDB(this.config).describeTable(params).promise() } async get(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.get(params) + return this.client.get(params).promise() } async update(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.update(params) + return this.client.update(params).promise() } async delete(query: { table: string - json: Omit + json: Omit }) { const params = { TableName: query.table, ...query.json, } - return this.client.delete(params) + return this.client.delete(params).promise() } } diff --git a/packages/server/src/integrations/s3.ts b/packages/server/src/integrations/s3.ts index 488c22835a..0b7d774048 100644 --- a/packages/server/src/integrations/s3.ts +++ b/packages/server/src/integrations/s3.ts @@ -7,9 +7,8 @@ import { ConnectionInfo, } from "@budibase/types" -import { S3 } from "@aws-sdk/client-s3" +import AWS from "aws-sdk" import csv from "csvtojson" -import stream from "stream" interface S3Config { region: string @@ -168,7 +167,7 @@ class S3Integration implements IntegrationBase { delete this.config.endpoint } - this.client = new S3(this.config) + this.client = new AWS.S3(this.config) } async testConnection() { @@ -176,7 +175,7 @@ class S3Integration implements IntegrationBase { connected: false, } try { - await this.client.listBuckets() + await this.client.listBuckets().promise() response.connected = true } catch (e: any) { response.error = e.message as string @@ -210,7 +209,7 @@ class S3Integration implements IntegrationBase { LocationConstraint: query.location, } } - return await this.client.createBucket(params) + return await this.client.createBucket(params).promise() } async read(query: { @@ -221,39 +220,37 @@ class S3Integration implements IntegrationBase { maxKeys: number prefix: string }) { - const response = await this.client.listObjects({ - Bucket: query.bucket, - Delimiter: query.delimiter, - Marker: query.marker, - MaxKeys: query.maxKeys, - Prefix: query.prefix, - }) + const response = await this.client + .listObjects({ + Bucket: query.bucket, + Delimiter: query.delimiter, + Marker: query.marker, + MaxKeys: query.maxKeys, + Prefix: query.prefix, + }) + .promise() return response.Contents } async readCsv(query: { bucket: string; key: string }) { - const response = await this.client.getObject({ - Bucket: query.bucket, - Key: query.key, - }) - - const fileStream = response.Body?.transformToWebStream() - - if (!fileStream || !(fileStream instanceof stream.Readable)) { - throw new Error("Unable to retrieve CSV - invalid stream") - } + const stream = this.client + .getObject({ + Bucket: query.bucket, + Key: query.key, + }) + .createReadStream() let csvError = false return new Promise((resolve, reject) => { - fileStream.on("error", (err: Error) => { + stream.on("error", (err: Error) => { reject(err) }) const response = csv() - .fromStream(fileStream) + .fromStream(stream) .on("error", () => { csvError = true }) - fileStream.on("finish", () => { + stream.on("finish", () => { resolve(response) }) }).catch(err => { @@ -266,10 +263,12 @@ class S3Integration implements IntegrationBase { } async delete(query: { bucket: string; delete: string }) { - return await this.client.deleteObjects({ - Bucket: query.bucket, - Delete: JSON.parse(query.delete), - }) + return await this.client + .deleteObjects({ + Bucket: query.bucket, + Delete: JSON.parse(query.delete), + }) + .promise() } } diff --git a/packages/server/src/integrations/tests/aws-sdk.mock.ts b/packages/server/src/integrations/tests/aws-sdk.mock.ts new file mode 100644 index 0000000000..0422adfd3c --- /dev/null +++ b/packages/server/src/integrations/tests/aws-sdk.mock.ts @@ -0,0 +1,76 @@ +const response = (body: any, extra?: any) => () => ({ + promise: () => body, + ...extra, +}) + +class DocumentClient { + put = jest.fn(response({})) + query = jest.fn( + response({ + Items: [], + }) + ) + scan = jest.fn( + response({ + Items: [ + { + Name: "test", + }, + ], + }) + ) + get = jest.fn(response({})) + update = jest.fn(response({})) + delete = jest.fn(response({})) +} + +class S3 { + listObjects = jest.fn( + response({ + Contents: [], + }) + ) + createBucket = jest.fn( + response({ + Contents: {}, + }) + ) + deleteObjects = jest.fn( + response({ + Contents: {}, + }) + ) + getSignedUrl = jest.fn((operation, params) => { + return `http://example.com/${params.Bucket}/${params.Key}` + }) + headBucket = jest.fn( + response({ + Contents: {}, + }) + ) + upload = jest.fn( + response({ + Contents: {}, + }) + ) + getObject = jest.fn( + response( + { + Body: "", + }, + { + createReadStream: jest.fn().mockReturnValue("stream"), + } + ) + ) +} + +module.exports = { + DynamoDB: { + DocumentClient, + }, + S3, + config: { + update: jest.fn(), + }, +} diff --git a/packages/server/src/integrations/tests/dynamodb.spec.ts b/packages/server/src/integrations/tests/dynamodb.spec.ts index 75fb84ae60..c992bc8bfd 100644 --- a/packages/server/src/integrations/tests/dynamodb.spec.ts +++ b/packages/server/src/integrations/tests/dynamodb.spec.ts @@ -1,20 +1,4 @@ -jest.mock("@aws-sdk/lib-dynamodb", () => ({ - DynamoDBDocument: { - from: jest.fn(() => ({ - update: jest.fn(), - put: jest.fn(), - query: jest.fn(() => ({ - Items: [], - })), - scan: jest.fn(() => ({ - Items: [], - })), - delete: jest.fn(), - get: jest.fn(), - })), - }, -})) -jest.mock("@aws-sdk/client-dynamodb") +jest.mock("aws-sdk", () => require("./aws-sdk.mock")) import { default as DynamoDBIntegration } from "../dynamodb" class TestConfiguration { @@ -73,7 +57,11 @@ describe("DynamoDB Integration", () => { TableName: tableName, IndexName: indexName, }) - expect(response).toEqual([]) + expect(response).toEqual([ + { + Name: "test", + }, + ]) }) it("calls the get method with the correct params", async () => { diff --git a/packages/server/src/integrations/tests/s3.spec.ts b/packages/server/src/integrations/tests/s3.spec.ts index 678f15bf17..abe8fb9cf1 100644 --- a/packages/server/src/integrations/tests/s3.spec.ts +++ b/packages/server/src/integrations/tests/s3.spec.ts @@ -1,52 +1,5 @@ +jest.mock("aws-sdk", () => require("./aws-sdk.mock")) import { default as S3Integration } from "../s3" -jest.mock("@aws-sdk/client-s3", () => { - class S3Mock { - response(body: any, extra?: any) { - return () => ({ - promise: () => body, - ...extra, - }) - } - - listObjects = jest.fn( - this.response({ - Contents: [], - }) - ) - createBucket = jest.fn( - this.response({ - Contents: {}, - }) - ) - deleteObjects = jest.fn( - this.response({ - Contents: {}, - }) - ) - headBucket = jest.fn( - this.response({ - Contents: {}, - }) - ) - upload = jest.fn( - this.response({ - Contents: {}, - }) - ) - getObject = jest.fn( - this.response( - { - Body: "", - }, - { - createReadStream: jest.fn().mockReturnValue("stream"), - } - ) - ) - } - - return { S3: S3Mock } -}) class TestConfiguration { integration: any diff --git a/packages/server/src/integrations/utils/utils.ts b/packages/server/src/integrations/utils/utils.ts index db9148ae90..315a8010e8 100644 --- a/packages/server/src/integrations/utils/utils.ts +++ b/packages/server/src/integrations/utils/utils.ts @@ -430,7 +430,7 @@ export async function handleFileResponse( size = details.ContentLength } } - presignedUrl = await objectStore.getPresignedUrl(bucket, key) + presignedUrl = objectStore.getPresignedUrl(bucket, key) return { data: { size, diff --git a/packages/server/src/sdk/plugins/plugins.ts b/packages/server/src/sdk/plugins/plugins.ts index bff24dcef7..63f2f22cd9 100644 --- a/packages/server/src/sdk/plugins/plugins.ts +++ b/packages/server/src/sdk/plugins/plugins.ts @@ -18,7 +18,7 @@ export async function fetch(type?: PluginType): Promise { }) ) let plugins = response.rows.map((row: any) => row.doc) as Plugin[] - plugins = await objectStore.enrichPluginURLs(plugins) + plugins = objectStore.enrichPluginURLs(plugins) if (type) { return plugins.filter((plugin: Plugin) => plugin.schema?.type === type) } else { diff --git a/packages/server/src/utilities/fileSystem/app.ts b/packages/server/src/utilities/fileSystem/app.ts index 642017d2da..9bd88ba0b1 100644 --- a/packages/server/src/utilities/fileSystem/app.ts +++ b/packages/server/src/utilities/fileSystem/app.ts @@ -78,7 +78,7 @@ export const getComponentLibraryManifest = async (library: string) => { resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path) } if (typeof resp !== "string") { - resp = resp.toString() + resp = resp.toString("utf8") } return JSON.parse(resp) } diff --git a/packages/server/src/utilities/fileSystem/plugin.ts b/packages/server/src/utilities/fileSystem/plugin.ts index 2949daef61..3e1e9bef4d 100644 --- a/packages/server/src/utilities/fileSystem/plugin.ts +++ b/packages/server/src/utilities/fileSystem/plugin.ts @@ -3,7 +3,6 @@ import { budibaseTempDir } from "../budibaseDir" import fs from "fs" import { join } from "path" import { objectStore } from "@budibase/backend-core" -import stream from "stream" const DATASOURCE_PATH = join(budibaseTempDir(), "datasource") const AUTOMATION_PATH = join(budibaseTempDir(), "automation") @@ -59,11 +58,7 @@ async function getPluginImpl(path: string, plugin: Plugin) { pluginKey ) - if (pluginJs instanceof stream.Readable) { - pluginJs.pipe(fs.createWriteStream(filename)) - } else { - fs.writeFileSync(filename, pluginJs) - } + fs.writeFileSync(filename, pluginJs) fs.writeFileSync(metadataName, hash) return require(filename) diff --git a/packages/server/src/utilities/rowProcessor/index.ts b/packages/server/src/utilities/rowProcessor/index.ts index 7c01c54f13..14b524fd95 100644 --- a/packages/server/src/utilities/rowProcessor/index.ts +++ b/packages/server/src/utilities/rowProcessor/index.ts @@ -359,9 +359,9 @@ export async function coreOutputProcessing( if (row[property] == null) { continue } - const process = async (attachment: RowAttachment) => { + const process = (attachment: RowAttachment) => { if (!attachment.url && attachment.key) { - attachment.url = await objectStore.getAppFileUrl(attachment.key) + attachment.url = objectStore.getAppFileUrl(attachment.key) } return attachment } @@ -369,13 +369,11 @@ export async function coreOutputProcessing( row[property] = JSON.parse(row[property]) } if (Array.isArray(row[property])) { - await Promise.all( - row[property].map((attachment: RowAttachment) => - process(attachment) - ) - ) + row[property].forEach((attachment: RowAttachment) => { + process(attachment) + }) } else { - await process(row[property]) + process(row[property]) } } } else if ( diff --git a/packages/worker/src/api/controllers/global/configs.ts b/packages/worker/src/api/controllers/global/configs.ts index 4ee8dcbb24..a10fce35f6 100644 --- a/packages/worker/src/api/controllers/global/configs.ts +++ b/packages/worker/src/api/controllers/global/configs.ts @@ -322,27 +322,27 @@ export async function save( } } -async function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) { +function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) { if (!oidcLogos) { return } - const newConfig: Record = {} - const keys = Object.keys(oidcLogos.config || {}) - - for (const key of keys) { - if (!key.endsWith("Etag")) { - const etag = oidcLogos.config[`${key}Etag`] - const objectStoreUrl = await objectStore.getGlobalFileUrl( - oidcLogos.type, - key, - etag - ) - newConfig[key] = objectStoreUrl - } else { - newConfig[key] = oidcLogos.config[key] - } - } - oidcLogos.config = newConfig + oidcLogos.config = Object.keys(oidcLogos.config || {}).reduce( + (acc: any, key: string) => { + if (!key.endsWith("Etag")) { + const etag = oidcLogos.config[`${key}Etag`] + const objectStoreUrl = objectStore.getGlobalFileUrl( + oidcLogos.type, + key, + etag + ) + acc[key] = objectStoreUrl + } else { + acc[key] = oidcLogos.config[key] + } + return acc + }, + {} + ) } export async function find(ctx: UserCtx) { @@ -370,7 +370,7 @@ export async function find(ctx: UserCtx) { async function handleConfigType(type: ConfigType, config: Config) { if (type === ConfigType.OIDC_LOGOS) { - await enrichOIDCLogos(config) + enrichOIDCLogos(config) } else if (type === ConfigType.AI) { await handleAIConfig(config) } @@ -396,7 +396,7 @@ export async function publicOidc(ctx: Ctx) { const oidcCustomLogos = await configs.getOIDCLogosDoc() if (oidcCustomLogos) { - await enrichOIDCLogos(oidcCustomLogos) + enrichOIDCLogos(oidcCustomLogos) } if (!oidcConfig) { @@ -427,7 +427,7 @@ export async function publicSettings( // enrich the logo url - empty url means deleted if (config.logoUrl && config.logoUrl !== "") { - config.logoUrl = await objectStore.getGlobalFileUrl( + config.logoUrl = objectStore.getGlobalFileUrl( "settings", "logoUrl", config.logoUrlEtag @@ -437,7 +437,7 @@ export async function publicSettings( // enrich the favicon url - empty url means deleted const faviconUrl = branding.faviconUrl && branding.faviconUrl !== "" - ? await objectStore.getGlobalFileUrl( + ? objectStore.getGlobalFileUrl( "settings", "faviconUrl", branding.faviconUrlEtag @@ -522,7 +522,7 @@ export async function upload(ctx: UserCtx) { ctx.body = { message: "File has been uploaded and url stored to config.", - url: await objectStore.getGlobalFileUrl(type, name, etag), + url: objectStore.getGlobalFileUrl(type, name, etag), } } diff --git a/yarn.lock b/yarn.lock index a9517925a8..c54385478e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -150,121 +150,6 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" -"@aws-sdk/client-dynamodb@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-dynamodb/-/client-dynamodb-3.709.0.tgz#589cfab9d27f7d0d2056f72e4674315ccd98b6bc" - integrity sha512-p/GVuEgfPccFUm5lxr7EPi5gQAsUO4SDdKcIV+v/dNwtH2SXEgnFN0o1TEIJtuVY3BsQyXyR1aMjeQ81O832kw== - dependencies: - "@aws-crypto/sha256-browser" "5.2.0" - "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.709.0" - "@aws-sdk/client-sts" "3.709.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/credential-provider-node" "3.709.0" - "@aws-sdk/middleware-endpoint-discovery" "3.709.0" - "@aws-sdk/middleware-host-header" "3.709.0" - "@aws-sdk/middleware-logger" "3.709.0" - "@aws-sdk/middleware-recursion-detection" "3.709.0" - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/region-config-resolver" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@aws-sdk/util-user-agent-browser" "3.709.0" - "@aws-sdk/util-user-agent-node" "3.709.0" - "@smithy/config-resolver" "^3.0.13" - "@smithy/core" "^2.5.5" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/hash-node" "^3.0.11" - "@smithy/invalid-dependency" "^3.0.11" - "@smithy/middleware-content-length" "^3.0.13" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-retry" "^3.0.30" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.30" - "@smithy/util-defaults-mode-node" "^3.0.30" - "@smithy/util-endpoints" "^2.1.7" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - "@smithy/util-utf8" "^3.0.0" - "@smithy/util-waiter" "^3.2.0" - "@types/uuid" "^9.0.1" - tslib "^2.6.2" - uuid "^9.0.1" - -"@aws-sdk/client-s3@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.709.0.tgz#ae27e18c5ced29f0d24857e4a28fb6947cdba3a4" - integrity sha512-IvC7coELoQ4YenTdULArVdL5yk6jNRVUALX1aqv9JlPdrXxb3Om6YrM9e7AlSTLxrULTsAe1ubm8i/DmcSY/Ng== - dependencies: - "@aws-crypto/sha1-browser" "5.2.0" - "@aws-crypto/sha256-browser" "5.2.0" - "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.709.0" - "@aws-sdk/client-sts" "3.709.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/credential-provider-node" "3.709.0" - "@aws-sdk/middleware-bucket-endpoint" "3.709.0" - "@aws-sdk/middleware-expect-continue" "3.709.0" - "@aws-sdk/middleware-flexible-checksums" "3.709.0" - "@aws-sdk/middleware-host-header" "3.709.0" - "@aws-sdk/middleware-location-constraint" "3.709.0" - "@aws-sdk/middleware-logger" "3.709.0" - "@aws-sdk/middleware-recursion-detection" "3.709.0" - "@aws-sdk/middleware-sdk-s3" "3.709.0" - "@aws-sdk/middleware-ssec" "3.709.0" - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/region-config-resolver" "3.709.0" - "@aws-sdk/signature-v4-multi-region" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@aws-sdk/util-user-agent-browser" "3.709.0" - "@aws-sdk/util-user-agent-node" "3.709.0" - "@aws-sdk/xml-builder" "3.709.0" - "@smithy/config-resolver" "^3.0.13" - "@smithy/core" "^2.5.5" - "@smithy/eventstream-serde-browser" "^3.0.14" - "@smithy/eventstream-serde-config-resolver" "^3.0.11" - "@smithy/eventstream-serde-node" "^3.0.13" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/hash-blob-browser" "^3.1.10" - "@smithy/hash-node" "^3.0.11" - "@smithy/hash-stream-node" "^3.1.10" - "@smithy/invalid-dependency" "^3.0.11" - "@smithy/md5-js" "^3.0.11" - "@smithy/middleware-content-length" "^3.0.13" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-retry" "^3.0.30" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.30" - "@smithy/util-defaults-mode-node" "^3.0.30" - "@smithy/util-endpoints" "^2.1.7" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - "@smithy/util-stream" "^3.3.2" - "@smithy/util-utf8" "^3.0.0" - "@smithy/util-waiter" "^3.2.0" - tslib "^2.6.2" - "@aws-sdk/client-s3@^3.388.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.693.0.tgz#188b621498ffaeb7b1ea5794f61e3e8d9a4bcac2" @@ -374,51 +259,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sso-oidc@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.709.0.tgz#959e4df4070f1d059d8d0cd5b9028d9a46ac7ecf" - integrity sha512-1w6egz17QQy661lNCRmZZlqIANEbD6g2VFAQIJbVwSiu7brg+GUns+mT1eLLLHAMQc1sL0Ds8/ybSK2SrgGgIA== - dependencies: - "@aws-crypto/sha256-browser" "5.2.0" - "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/credential-provider-node" "3.709.0" - "@aws-sdk/middleware-host-header" "3.709.0" - "@aws-sdk/middleware-logger" "3.709.0" - "@aws-sdk/middleware-recursion-detection" "3.709.0" - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/region-config-resolver" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@aws-sdk/util-user-agent-browser" "3.709.0" - "@aws-sdk/util-user-agent-node" "3.709.0" - "@smithy/config-resolver" "^3.0.13" - "@smithy/core" "^2.5.5" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/hash-node" "^3.0.11" - "@smithy/invalid-dependency" "^3.0.11" - "@smithy/middleware-content-length" "^3.0.13" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-retry" "^3.0.30" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.30" - "@smithy/util-defaults-mode-node" "^3.0.30" - "@smithy/util-endpoints" "^2.1.7" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@aws-sdk/client-sso@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz#9cd5e07e57013b8c7980512810d775d7b6f67e36" @@ -463,50 +303,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sso@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.709.0.tgz#b5b29161e07af6f82afd7a6e750c09b0158d19e3" - integrity sha512-Qxeo8cN0jNy6Wnbqq4wucffAGJM6sJjofoTgNtPA6cC7sPYx7aYC6OAAAo6NaMRY+WywOKdS9Wgjx2QYRxKx7w== - dependencies: - "@aws-crypto/sha256-browser" "5.2.0" - "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/middleware-host-header" "3.709.0" - "@aws-sdk/middleware-logger" "3.709.0" - "@aws-sdk/middleware-recursion-detection" "3.709.0" - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/region-config-resolver" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@aws-sdk/util-user-agent-browser" "3.709.0" - "@aws-sdk/util-user-agent-node" "3.709.0" - "@smithy/config-resolver" "^3.0.13" - "@smithy/core" "^2.5.5" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/hash-node" "^3.0.11" - "@smithy/invalid-dependency" "^3.0.11" - "@smithy/middleware-content-length" "^3.0.13" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-retry" "^3.0.30" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.30" - "@smithy/util-defaults-mode-node" "^3.0.30" - "@smithy/util-endpoints" "^2.1.7" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@aws-sdk/client-sts@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz#9e2c418f4850269635632bee4d1a31057c04bcc5" @@ -553,52 +349,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sts@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.709.0.tgz#b9ad3c9c6419d0d149b28cdd6c115cc40c4e7906" - integrity sha512-cBAvlPg6yslXNL385UUGFPw+XY+lA9BzioNdIFkMo3fEUlTShogTtiWz4LsyLHoN6LhKojssP9DSmmWKWjCZIw== - dependencies: - "@aws-crypto/sha256-browser" "5.2.0" - "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.709.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/credential-provider-node" "3.709.0" - "@aws-sdk/middleware-host-header" "3.709.0" - "@aws-sdk/middleware-logger" "3.709.0" - "@aws-sdk/middleware-recursion-detection" "3.709.0" - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/region-config-resolver" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@aws-sdk/util-user-agent-browser" "3.709.0" - "@aws-sdk/util-user-agent-node" "3.709.0" - "@smithy/config-resolver" "^3.0.13" - "@smithy/core" "^2.5.5" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/hash-node" "^3.0.11" - "@smithy/invalid-dependency" "^3.0.11" - "@smithy/middleware-content-length" "^3.0.13" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-retry" "^3.0.30" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.30" - "@smithy/util-defaults-mode-node" "^3.0.30" - "@smithy/util-endpoints" "^2.1.7" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@aws-sdk/core@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.693.0.tgz#437969dd740895a59863d737bad14646bc2e1725" @@ -616,23 +366,6 @@ fast-xml-parser "4.4.1" tslib "^2.6.2" -"@aws-sdk/core@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.709.0.tgz#d2b3d5b90f6614e3afc109ebdcaaedbb54c2d68b" - integrity sha512-7kuSpzdOTAE026j85wq/fN9UDZ70n0OHw81vFqMWwlEFtm5IQ/MRCLKcC4HkXxTdfy1PqFlmoXxWqeBa15tujw== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/core" "^2.5.5" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/property-provider" "^3.1.11" - "@smithy/protocol-http" "^4.1.8" - "@smithy/signature-v4" "^4.2.4" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/util-middleware" "^3.0.11" - fast-xml-parser "4.4.1" - tslib "^2.6.2" - "@aws-sdk/credential-provider-env@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.693.0.tgz#f97feed9809fe2800216943470015fdaaba47c4f" @@ -644,17 +377,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.709.0.tgz#a7f75375d8a413f9ab2bc42f743b943da6d3362d" - integrity sha512-ZMAp9LSikvHDFVa84dKpQmow6wsg956Um20cKuioPpX2GGreJFur7oduD+tRJT6FtIOHn+64YH+0MwiXLhsaIQ== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/property-provider" "^3.1.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-http@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz#5caad0ac47eded1edeb63f907280580ccfaadba3" @@ -671,22 +393,6 @@ "@smithy/util-stream" "^3.3.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.709.0.tgz#a378cbcc4cf373cc277944f1e84e9952f3884f5d" - integrity sha512-lIS7XLwCOyJnLD70f+VIRr8DNV1HPQe9oN6aguYrhoczqz7vDiVZLe3lh714cJqq9rdxzFypK5DqKHmcscMEPQ== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/property-provider" "^3.1.11" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/util-stream" "^3.3.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-ini@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz#b4557ac1092657660a15c9bd55e17c27f79ec621" @@ -705,24 +411,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.709.0.tgz#b01c68d98ce4cc48f79405234e32a9de2f943ea1" - integrity sha512-qCF8IIGcPoUp+Ib3ANhbF5gElxFd+kIrtv2/1tKdvhudMANstQbMiWV0LTH47ZZR6c3as4iSrm09NZnpEoD/pA== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/credential-provider-env" "3.709.0" - "@aws-sdk/credential-provider-http" "3.709.0" - "@aws-sdk/credential-provider-process" "3.709.0" - "@aws-sdk/credential-provider-sso" "3.709.0" - "@aws-sdk/credential-provider-web-identity" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/credential-provider-imds" "^3.2.8" - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-node@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz#c5ceac64a69304d5b4db3fd68473480cafddb4a9" @@ -741,24 +429,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.709.0.tgz#270a31aae394e6c8fe7d3fdd0b92e7c3a863b933" - integrity sha512-4HRX9KYWPSjO5O/Vg03YAsebKpvTjTvpK1n7zHYBmlLMBLxUrVsL1nNKKC5p2/7OW3RL8XR1ki3QkoV7kGRxUQ== - dependencies: - "@aws-sdk/credential-provider-env" "3.709.0" - "@aws-sdk/credential-provider-http" "3.709.0" - "@aws-sdk/credential-provider-ini" "3.709.0" - "@aws-sdk/credential-provider-process" "3.709.0" - "@aws-sdk/credential-provider-sso" "3.709.0" - "@aws-sdk/credential-provider-web-identity" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/credential-provider-imds" "^3.2.8" - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-process@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.693.0.tgz#e84e945f1a148f06ff697608d5309e73347e5aa9" @@ -771,18 +441,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.709.0.tgz#2521f810590f0874c54cc842d3d56f455a728325" - integrity sha512-IAC+jPlGQII6jhIylHOwh3RgSobqlgL59nw2qYTURr8hMCI0Z1p5y2ee646HTVt4WeCYyzUAXfxr6YI/Vitv+Q== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-sso@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz#72767389f533d9d17a14af63daaafcc8368ab43a" @@ -797,20 +455,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.709.0.tgz#f0cb855eed86748ff0c9afa06b3a234fb04b3206" - integrity sha512-rYdTDOxazS2GdGScelsRK5CAkktRLCCdRjlwXaxrcW57j749hEqxcF5uTv9RD6WBwInfedcSywErNZB+hylQlg== - dependencies: - "@aws-sdk/client-sso" "3.709.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/token-providers" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/credential-provider-web-identity@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz#b6133b5ef9d3582e36e02e9c66766714ff672a11" @@ -822,50 +466,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.709.0.tgz#c2b03541cb57ae4c7d6abdca98f99a6a56833ea6" - integrity sha512-2lbDfE0IQ6gma/7BB2JpkjW5G0wGe4AS0x80oybYAYYviJmUtIR3Cn2pXun6bnAWElt4wYKl4su7oC36rs5rNA== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/property-provider" "^3.1.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - -"@aws-sdk/endpoint-cache@3.693.0": - version "3.693.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/endpoint-cache/-/endpoint-cache-3.693.0.tgz#4b3f0bbc16dc2907e1b977e3d8ddfc7ba008fd12" - integrity sha512-/zK0ZZncBf5FbTfo8rJMcQIXXk4Ibhe5zEMiwFNivVPR2uNC0+oqfwXz7vjxwY0t6BPE3Bs4h9uFEz4xuGCY6w== - dependencies: - mnemonist "0.38.3" - tslib "^2.6.2" - -"@aws-sdk/lib-dynamodb@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.709.0.tgz#fd90b76bce67af1a3079524710f7bc19647829ad" - integrity sha512-piIyvQ1DhoUEosKmjGnMxLClUb9tv5rPPZfgh9J4MmSygsYbE9HvC3tstje0xUudVZjsmzZpNyibl/n0LA0gdQ== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/util-dynamodb" "3.709.0" - "@smithy/core" "^2.5.5" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - -"@aws-sdk/lib-storage@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.709.0.tgz#2b12e558880418c3348cbd8f1e4e7f8db424b7b7" - integrity sha512-TnP+QSsWdiaQYS5HuB3n9H947z49m6qSEv5fth4L9xinBldLepLyyF+cua3/GlagkWqpxcATISgR9pE1PB0mhQ== - dependencies: - "@smithy/abort-controller" "^3.1.9" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/smithy-client" "^3.5.0" - buffer "5.6.0" - events "3.3.0" - stream-browserify "3.0.0" - tslib "^2.6.2" - "@aws-sdk/middleware-bucket-endpoint@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.693.0.tgz#e4823a40935d34f5e58a4fbc830d8ff92e44fc99" @@ -879,31 +479,6 @@ "@smithy/util-config-provider" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-bucket-endpoint@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.709.0.tgz#a69bdebfebb7b5b174d3a396f2361f5025d168f4" - integrity sha512-03+tJOd7KIZOiqWH7Z8BOfQIWkKJgjcpKOJKZ6FR2KjWGUOE1G+bo11wF4UuHQ0RmpKnApt+pQghZmSnE7WEeg== - dependencies: - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-arn-parser" "3.693.0" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - "@smithy/util-config-provider" "^3.0.0" - tslib "^2.6.2" - -"@aws-sdk/middleware-endpoint-discovery@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.709.0.tgz#d5866603f2515f0da2c84ead99cd25b806d8ee5b" - integrity sha512-6CSHoAy3sVBJdeGiBpoRqVHpqLPqv5QuDxKsEMHoGdbGATmffyn2whTFfo5hfRYsN9WPz/XxUX2iynqQCnlrzw== - dependencies: - "@aws-sdk/endpoint-cache" "3.693.0" - "@aws-sdk/types" "3.709.0" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-expect-continue@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.693.0.tgz#d8696cee9ebea1d973d8daf872fd913b41d62cf0" @@ -914,16 +489,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-expect-continue@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.709.0.tgz#a7fec776da9de32e15088badfc09d69118f5d5ab" - integrity sha512-Tbl/DFvE4rHl8lMb9IzetwK4tf5R3VeHZkvEXQalsWoK0tbEQ8kXWi7wAYO4qbE7bFVvaxKX+irjJjTxf3BrCQ== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-flexible-checksums@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.693.0.tgz#80f07802d98ff33a6899a09c59cf51aab426aaac" @@ -943,25 +508,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-flexible-checksums@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.709.0.tgz#f0fb543c2db724cb43bae215ff0aea942d06a967" - integrity sha512-wbYm9tkyCaqMeU82yjaXw7V5BxCSlSLNupENW63LC7Fvyo/aQzj6LjSMHcBpR2QwjBEhXCtF47L7aQ8SPTNhdw== - dependencies: - "@aws-crypto/crc32" "5.2.0" - "@aws-crypto/crc32c" "5.2.0" - "@aws-crypto/util" "5.2.0" - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/is-array-buffer" "^3.0.0" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-stream" "^3.3.2" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@aws-sdk/middleware-host-header@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz#69322909c0792df1e6be7c7fb5e2b6f76090a55c" @@ -972,16 +518,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-host-header@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.709.0.tgz#f44f5c62f9bd7e5a443603fed68143d2d9725219" - integrity sha512-8gQYCYAaIw4lOCd5WYdf15Y/61MgRsAnrb2eiTl+icMlUOOzl8aOl5iDwm/Idp0oHZTflwxM4XSvGXO83PRWcw== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-location-constraint@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.693.0.tgz#1856eaaad64d41d1f8fa53ced58a6c7cf5eccc6e" @@ -991,15 +527,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-location-constraint@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.709.0.tgz#4437d3d3cfbbdfca60664b1f237d600b94fd06a5" - integrity sha512-5YQWPXfZq7OE0jB2G0PP8K10GBod/YPJXb+1CfJS6FbQaglRoIm8KZmVEvJNnptSKyGtE62veeCcCQcfAUfFig== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-logger@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz#fc10294e6963f8e5d58ba1ededd891e999f544a9" @@ -1009,15 +536,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-logger@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.709.0.tgz#b9a0b016b7ae09cb502cc4faf45964d4b5745824" - integrity sha512-jDoGSccXv9zebnpUoisjWd5u5ZPIalrmm6TjvPzZ8UqzQt3Beiz0tnQwmxQD6KRc7ADweWP5Ntiqzbw9xpVajg== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-recursion-detection@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz#88a8157293775e7116707da26501da4b5e042f51" @@ -1028,16 +546,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-recursion-detection@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.709.0.tgz#d7dc253d4858d496caeb12dd6cddd87b250fb98b" - integrity sha512-PObL/wLr4lkfbQ0yXUWaoCWu/jcwfwZzCjsUiXW/H6hW9b/00enZxmx7OhtJYaR6xmh/Lcx5wbhIoDCbzdv0tw== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-sdk-s3@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.693.0.tgz#e0850854d5079f372786b2ccfe85729caa7a49d8" @@ -1058,26 +566,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-sdk-s3@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.709.0.tgz#b6f22c77e64760869eb06255af58376f879742b2" - integrity sha512-FwtOG9t9xsLoLOQZ6qAdsWOjx9dsO6t28IjIDV1l6Ixiu2oC0Yks7goONjJUH0IDE4pDDDGzmuq0sn1XtHhheA== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-arn-parser" "3.693.0" - "@smithy/core" "^2.5.5" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/protocol-http" "^4.1.8" - "@smithy/signature-v4" "^4.2.4" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-stream" "^3.3.2" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@aws-sdk/middleware-ssec@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.693.0.tgz#2ff779147d188090b3a6cda3ed12ca4085220a73" @@ -1087,15 +575,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-ssec@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.709.0.tgz#bbf5253cdce45ed2759a108fd924fff4b8e049d5" - integrity sha512-2muiLe7YkmlwZp2SKz+goZrDThGfRq3o0FcJF3Puc0XGmcEPEDjih537mCoTrGgcXNFlBc7YChd84r3t72ySaQ== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/middleware-user-agent@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz#4b55cfab3fc7e671b08e1ea63a98e45a1e13e6a5" @@ -1109,19 +588,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.709.0.tgz#2a467f14b3f4a9270bcdfde32e3d4e38701aaafe" - integrity sha512-ooc9ZJvgkjPhi9q05XwSfNTXkEBEIfL4hleo5rQBKwHG3aTHvwOM7LLzhdX56QZVa6sorPBp6fwULuRDSqiQHw== - dependencies: - "@aws-sdk/core" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-endpoints" "3.709.0" - "@smithy/core" "^2.5.5" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/node-http-handler@^3.374.0": version "3.374.0" resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.374.0.tgz#8cd58b4d9814713e26034c12eabc119c113a5bc4" @@ -1142,32 +608,6 @@ "@smithy/util-middleware" "^3.0.9" tslib "^2.6.2" -"@aws-sdk/region-config-resolver@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.709.0.tgz#64547b333842e5804e1793e4d6d29578c0b34a68" - integrity sha512-/NoCAMEVKAg3kBKOrNtgOfL+ECt6nrl+L7q2SyYmrcY4tVCmwuECVqewQaHc03fTnJijfKLccw0Fj+6wOCnB6w== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/types" "^3.7.2" - "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.11" - tslib "^2.6.2" - -"@aws-sdk/s3-request-presigner@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.709.0.tgz#d3c9d881158bdece69863be318d49e9d7d2c512f" - integrity sha512-WYmXU2ur/z6xBX9TcGwSWlSiS8rxrRl2f1HJXZzgSu9FWZ7fJssoQGvrk/w64wjNq1tEzKbd1iWXw9s9qexT3g== - dependencies: - "@aws-sdk/signature-v4-multi-region" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@aws-sdk/util-format-url" "3.709.0" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/protocol-http" "^4.1.8" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/signature-v4-multi-region@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.693.0.tgz#85bd90bb78be1a98d5a5ca41033cb0703146c2c4" @@ -1180,18 +620,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/signature-v4-multi-region@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.709.0.tgz#0c6f9d3e2978158163b63a4085356616237223c9" - integrity sha512-m0vhJEy6SLbjL11K9cHzX/ZhCIj//1GkTbYk2d4tTQFSuPyJEkjmoeHk9dYm2mJy0wH48j29OJadI1JUsR5bOw== - dependencies: - "@aws-sdk/middleware-sdk-s3" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/protocol-http" "^4.1.8" - "@smithy/signature-v4" "^4.2.4" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/token-providers@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz#5ce7d6aa7a3437d4abdc0dca1be47f5158d15c85" @@ -1203,17 +631,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/token-providers@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.709.0.tgz#56305ab187660a711fd172c329dc953ca754fa80" - integrity sha512-q5Ar6k71nci43IbULFgC8a89d/3EHpmd7HvBzqVGRcHnoPwh8eZDBfbBXKH83NGwcS1qPSRYiDbVfeWPm4/1jA== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/types@3.692.0", "@aws-sdk/types@^3.222.0": version "3.692.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.692.0.tgz#c8f6c75b6ad659865b72759796d4d92c1b72069b" @@ -1222,14 +639,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/types@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.709.0.tgz#f8d7ab07e253d3ed0e3b360e09fc67c7430a73b9" - integrity sha512-ArtLTMxgjf13Kfu3gWH3Ez9Q5TkDdcRZUofpKH3pMGB/C6KAbeSCtIIDKfoRTUABzyGlPyCrZdnFjKyH+ypIpg== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/util-arn-parser@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.693.0.tgz#8dae27eb822ab4f88be28bb3c0fc11f1f13d3948" @@ -1237,13 +646,6 @@ dependencies: tslib "^2.6.2" -"@aws-sdk/util-dynamodb@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-dynamodb/-/util-dynamodb-3.709.0.tgz#12ced0849ff8f1ac8a1921f97fdb57813f22ec14" - integrity sha512-rGr9+Po6Ma2BHV2hIhfXdn8hWxLtmgFzFRqqtxOlRRIDN55wkb2AYXz/ydzf4kgb+PzT8sQxtn6hf7pDkl+yAg== - dependencies: - tslib "^2.6.2" - "@aws-sdk/util-endpoints@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz#99f56f83fc25bdc3321f5871d6354abd56768891" @@ -1254,26 +656,6 @@ "@smithy/util-endpoints" "^2.1.5" tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.709.0.tgz#32dfe339d78b699ada68392bbb3bec25441bae5c" - integrity sha512-Mbc7AtL5WGCTKC16IGeUTz+sjpC3ptBda2t0CcK0kMVw3THDdcSq6ZlNKO747cNqdbwUvW34oHteUiHv4/z88Q== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/types" "^3.7.2" - "@smithy/util-endpoints" "^2.1.7" - tslib "^2.6.2" - -"@aws-sdk/util-format-url@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-format-url/-/util-format-url-3.709.0.tgz#6ac420c297cae442f6d4065214eefc0d977e1a10" - integrity sha512-HGR11hx1KeFfoub/TACf+Yyal37lR85791Di2QPaElQThaqztLlppxale3EohKboOFf7Q/zvslJyM0fmgrlpQw== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/querystring-builder" "^3.0.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/util-locate-window@^3.0.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz#1160f6d055cf074ca198eb8ecf89b6311537ad6c" @@ -1291,16 +673,6 @@ bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-browser@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.709.0.tgz#ad6e867bdd348923ec10ddd6c37740ce0986cd8f" - integrity sha512-/rL2GasJzdTWUURCQKFldw2wqBtY4k4kCiA2tVZSKg3y4Ey7zO34SW8ebaeCE2/xoWOyLR2/etdKyphoo4Zrtg== - dependencies: - "@aws-sdk/types" "3.709.0" - "@smithy/types" "^3.7.2" - bowser "^2.11.0" - tslib "^2.6.2" - "@aws-sdk/util-user-agent-node@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz#b26c806faa2001d4fa1d515b146eeff411513dd9" @@ -1312,17 +684,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.709.0.tgz#7ff5a508bcad49963a550acadcced43d7af9960d" - integrity sha512-trBfzSCVWy7ILgqhEXgiuM7hfRCw4F4a8IK90tjk9YL0jgoJ6eJuOp7+DfCtHJaygoBxD3cdMFkOu+lluFmGBA== - dependencies: - "@aws-sdk/middleware-user-agent" "3.709.0" - "@aws-sdk/types" "3.709.0" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@aws-sdk/xml-builder@3.693.0": version "3.693.0" resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.693.0.tgz#709a46a3335b71144d9f7917a7cb3033b5a04e82" @@ -1331,14 +692,6 @@ "@smithy/types" "^3.7.0" tslib "^2.6.2" -"@aws-sdk/xml-builder@3.709.0": - version "3.709.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.709.0.tgz#5841faa1e78afcea064557a1a56709978b325758" - integrity sha512-2GPCwlNxeHspoK/Mc8nbk9cBOkSpp3j2SJUQmFnyQK6V/pR6II2oPRyZkMomug1Rc10hqlBHByMecq4zhV2uUw== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@azure/abort-controller@^1.0.0", "@azure/abort-controller@^1.0.4": version "1.1.0" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.1.0.tgz#788ee78457a55af8a1ad342acb182383d2119249" @@ -4871,14 +4224,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/abort-controller@^3.1.9": - version "3.1.9" - resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-3.1.9.tgz#47d323f754136a489e972d7fd465d534d72fcbff" - integrity sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/chunked-blob-reader-native@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.1.tgz#39045ed278ee1b6f4c12715c7565678557274c29" @@ -4905,17 +4250,6 @@ "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" -"@smithy/config-resolver@^3.0.13": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-3.0.13.tgz#653643a77a33d0f5907a5e7582353886b07ba752" - integrity sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg== - dependencies: - "@smithy/node-config-provider" "^3.1.12" - "@smithy/types" "^3.7.2" - "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.11" - tslib "^2.6.2" - "@smithy/core@^2.5.2", "@smithy/core@^2.5.3": version "2.5.3" resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.3.tgz#1d5723f676b0d6ec08c515272f0ac03aa59fac72" @@ -4930,20 +4264,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/core@^2.5.5": - version "2.5.5" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.5.tgz#c75b15caee9e58c800db3e6b99e9e373532d394a" - integrity sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw== - dependencies: - "@smithy/middleware-serde" "^3.0.11" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-stream" "^3.3.2" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/credential-provider-imds@^3.2.6", "@smithy/credential-provider-imds@^3.2.7": version "3.2.7" resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz#6eedf87ba0238723ec46d8ce0f18e276685a702d" @@ -4955,27 +4275,6 @@ "@smithy/url-parser" "^3.0.10" tslib "^2.6.2" -"@smithy/credential-provider-imds@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz#27ed2747074c86a7d627a98e56f324a65cba88de" - integrity sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw== - dependencies: - "@smithy/node-config-provider" "^3.1.12" - "@smithy/property-provider" "^3.1.11" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - tslib "^2.6.2" - -"@smithy/eventstream-codec@^3.1.10": - version "3.1.10" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz#0c1a3457e7a23b71cd71525ceb668f8569a84dad" - integrity sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ== - dependencies: - "@aws-crypto/crc32" "5.2.0" - "@smithy/types" "^3.7.2" - "@smithy/util-hex-encoding" "^3.0.0" - tslib "^2.6.2" - "@smithy/eventstream-codec@^3.1.9": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz#4271354e75e57d30771fca307da403896c657430" @@ -4995,23 +4294,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/eventstream-serde-browser@^3.0.14": - version "3.0.14" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz#0c3584c7cde2e210aacdfbbd2b57c1d7e2ca3b95" - integrity sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg== - dependencies: - "@smithy/eventstream-serde-universal" "^3.0.13" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - -"@smithy/eventstream-serde-config-resolver@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz#5edceba836debea165ea93145231036f6286d67c" - integrity sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/eventstream-serde-config-resolver@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz#5c0b2ae0bb8e11cfa77851098e46f7350047ec8d" @@ -5029,15 +4311,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/eventstream-serde-node@^3.0.13": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz#5aebd7b553becee277e411a2b69f6af8c9d7b3a6" - integrity sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ== - dependencies: - "@smithy/eventstream-serde-universal" "^3.0.13" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/eventstream-serde-universal@^3.0.12": version "3.0.12" resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz#803d7beb29a3de4a64e91af97331a4654741c35f" @@ -5047,15 +4320,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/eventstream-serde-universal@^3.0.13": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz#609c922ea14a0a3eed23a28ac110344c935704eb" - integrity sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw== - dependencies: - "@smithy/eventstream-codec" "^3.1.10" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/fetch-http-handler@^4.1.0", "@smithy/fetch-http-handler@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz#cead80762af4cdea11e7eeb627ea1c4835265dfa" @@ -5067,27 +4331,6 @@ "@smithy/util-base64" "^3.0.0" tslib "^2.6.2" -"@smithy/fetch-http-handler@^4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz#f034ff16416b37d92908a1381ef5fddbf4ef1879" - integrity sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA== - dependencies: - "@smithy/protocol-http" "^4.1.8" - "@smithy/querystring-builder" "^3.0.11" - "@smithy/types" "^3.7.2" - "@smithy/util-base64" "^3.0.0" - tslib "^2.6.2" - -"@smithy/hash-blob-browser@^3.1.10": - version "3.1.10" - resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.10.tgz#985e308189c2687a15004152b97506882ffb2b13" - integrity sha512-elwslXOoNunmfS0fh55jHggyhccobFkexLYC1ZeZ1xP2BTSrcIBaHV2b4xUQOdctrSNOpMqOZH1r2XzWTEhyfA== - dependencies: - "@smithy/chunked-blob-reader" "^4.0.0" - "@smithy/chunked-blob-reader-native" "^3.0.1" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/hash-blob-browser@^3.1.8": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.9.tgz#1f2c3ef6afbb0ce3e58a0129753850bb9267aae8" @@ -5098,16 +4341,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/hash-node@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.11.tgz#99e09ead3fc99c8cd7ca0f254ea0e35714f2a0d3" - integrity sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA== - dependencies: - "@smithy/types" "^3.7.2" - "@smithy/util-buffer-from" "^3.0.0" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/hash-node@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.10.tgz#93c857b4bff3a48884886440fd9772924887e592" @@ -5118,15 +4351,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/hash-stream-node@^3.1.10": - version "3.1.10" - resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.10.tgz#94716b4556f4ccf2807e605f47bb5b018ed7dfb0" - integrity sha512-olomK/jZQ93OMayW1zfTHwcbwBdhcZOHsyWyiZ9h9IXvc1mCD/VuvzbLb3Gy/qNJwI4MANPLctTp2BucV2oU/Q== - dependencies: - "@smithy/types" "^3.7.2" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/hash-stream-node@^3.1.8": version "3.1.9" resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.9.tgz#97eb416811b7e7b9d036f0271588151b619759e9" @@ -5136,14 +4360,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/invalid-dependency@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz#8144d7b0af9d34ab5f672e1f674f97f8740bb9ae" - integrity sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/invalid-dependency@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz#8616dee555916c24dec3e33b1e046c525efbfee3" @@ -5166,15 +4382,6 @@ dependencies: tslib "^2.6.2" -"@smithy/md5-js@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.11.tgz#27e4dab616348ff94aed24dc75e4017c582df40f" - integrity sha512-3NM0L3i2Zm4bbgG6Ymi9NBcxXhryi3uE8fIfHJZIOfZVxOkGdjdgjR9A06SFIZCfnEIWKXZdm6Yq5/aPXFFhsQ== - dependencies: - "@smithy/types" "^3.7.2" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/md5-js@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.10.tgz#52ab927cf03cd1d24fed82d8ba936faf5632436e" @@ -5193,15 +4400,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/middleware-content-length@^3.0.13": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz#6e08fe52739ac8fb3996088e0f8837e4b2ea187f" - integrity sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw== - dependencies: - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/middleware-endpoint@^3.2.2", "@smithy/middleware-endpoint@^3.2.3": version "3.2.3" resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz#7dd3df0052fc55891522631a7751e613b6efd68a" @@ -5216,20 +4414,6 @@ "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" -"@smithy/middleware-endpoint@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz#bdcfdf1f342cf933b0b8a709996f9a8fbb8148f4" - integrity sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg== - dependencies: - "@smithy/core" "^2.5.5" - "@smithy/middleware-serde" "^3.0.11" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - "@smithy/url-parser" "^3.0.11" - "@smithy/util-middleware" "^3.0.11" - tslib "^2.6.2" - "@smithy/middleware-retry@^3.0.26": version "3.0.27" resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz#2e4dda420178835cd2d416479505d313b601ba21" @@ -5245,21 +4429,6 @@ tslib "^2.6.2" uuid "^9.0.1" -"@smithy/middleware-retry@^3.0.30": - version "3.0.30" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.30.tgz#2580322d0d28ad782b5b8c07c150b14efdc3b2f9" - integrity sha512-6323RL2BvAR3VQpTjHpa52kH/iSHyxd/G9ohb2MkBk2Ucu+oMtRXT8yi7KTSIS9nb58aupG6nO0OlXnQOAcvmQ== - dependencies: - "@smithy/node-config-provider" "^3.1.12" - "@smithy/protocol-http" "^4.1.8" - "@smithy/service-error-classification" "^3.0.11" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-retry" "^3.0.11" - tslib "^2.6.2" - uuid "^9.0.1" - "@smithy/middleware-serde@^3.0.10", "@smithy/middleware-serde@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz#5f6c0b57b10089a21d355bd95e9b7d40378454d7" @@ -5268,14 +4437,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/middleware-serde@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz#c7d54e0add4f83e05c6878a011fc664e21022f12" - integrity sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/middleware-stack@^3.0.10", "@smithy/middleware-stack@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz#73e2fde5d151440844161773a17ee13375502baf" @@ -5284,14 +4445,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/middleware-stack@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz#453af2096924e4064d9da4e053cfdf65d9a36acc" - integrity sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/node-config-provider@^3.1.10", "@smithy/node-config-provider@^3.1.11": version "3.1.11" resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz#95feba85a5cb3de3fe9adfff1060b35fd556d023" @@ -5302,16 +4455,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/node-config-provider@^3.1.12": - version "3.1.12" - resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz#1b1d674fc83f943dc7b3017e37f16f374e878a6c" - integrity sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ== - dependencies: - "@smithy/property-provider" "^3.1.11" - "@smithy/shared-ini-file-loader" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/node-http-handler@^1.0.2": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-1.1.0.tgz#887cee930b520e08043c9f41e463f8d8f5dae127" @@ -5334,17 +4477,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/node-http-handler@^3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz#b34685863b74dabdaf7860aa81b42d0d5437c7e0" - integrity sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA== - dependencies: - "@smithy/abort-controller" "^3.1.9" - "@smithy/protocol-http" "^4.1.8" - "@smithy/querystring-builder" "^3.0.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/property-provider@^3.1.10", "@smithy/property-provider@^3.1.9": version "3.1.10" resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.10.tgz#ae00447c1060c194c3e1b9475f7c8548a70f8486" @@ -5353,14 +4485,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/property-provider@^3.1.11": - version "3.1.11" - resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.11.tgz#161cf1c2a2ada361e417382c57f5ba6fbca8acad" - integrity sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/protocol-http@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-1.2.0.tgz#a554e4dabb14508f0bc2cdef9c3710e2b294be04" @@ -5377,14 +4501,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/protocol-http@^4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-4.1.8.tgz#0461758671335f65e8ff3fc0885ab7ed253819c9" - integrity sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/querystring-builder@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-1.1.0.tgz#de6306104640ade34e59be33949db6cc64aa9d7f" @@ -5403,15 +4519,6 @@ "@smithy/util-uri-escape" "^3.0.0" tslib "^2.6.2" -"@smithy/querystring-builder@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz#2ed04adbe725671824c5613d0d6f9376d791a909" - integrity sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg== - dependencies: - "@smithy/types" "^3.7.2" - "@smithy/util-uri-escape" "^3.0.0" - tslib "^2.6.2" - "@smithy/querystring-parser@^3.0.10": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz#62db744a1ed2cf90f4c08d2c73d365e033b4a11c" @@ -5420,14 +4527,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/querystring-parser@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz#9d3177ea19ce8462f18d9712b395239e1ca1f969" - integrity sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/service-error-classification@^3.0.10": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz#941c549daf0e9abb84d3def1d9e1e3f0f74f5ba6" @@ -5435,13 +4534,6 @@ dependencies: "@smithy/types" "^3.7.1" -"@smithy/service-error-classification@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz#d3d7fc0aacd2e60d022507367e55c7939e5bcb8a" - integrity sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog== - dependencies: - "@smithy/types" "^3.7.2" - "@smithy/shared-ini-file-loader@^3.1.10", "@smithy/shared-ini-file-loader@^3.1.11": version "3.1.11" resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz#0b4f98c4a66480956fbbefc4627c5dc09d891aea" @@ -5450,14 +4542,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/shared-ini-file-loader@^3.1.12": - version "3.1.12" - resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz#d98b1b663eb18935ce2cbc79024631d34f54042a" - integrity sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/signature-v4@^4.2.2": version "4.2.3" resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.3.tgz#abbca5e5fe9158422b3125b2956791a325a27f22" @@ -5472,20 +4556,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/signature-v4@^4.2.4": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.4.tgz#3501d3d09fd82768867bfc00a7be4bad62f62f4d" - integrity sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA== - dependencies: - "@smithy/is-array-buffer" "^3.0.0" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - "@smithy/util-hex-encoding" "^3.0.0" - "@smithy/util-middleware" "^3.0.11" - "@smithy/util-uri-escape" "^3.0.0" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/smithy-client@^3.4.3", "@smithy/smithy-client@^3.4.4": version "3.4.4" resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.4.4.tgz#460870dc97d945fa2f390890359cf09d01131e0f" @@ -5499,26 +4569,6 @@ "@smithy/util-stream" "^3.3.1" tslib "^2.6.2" -"@smithy/smithy-client@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.5.0.tgz#65cff262801b009998c1196764ee69929ee06f8a" - integrity sha512-Y8FeOa7gbDfCWf7njrkoRATPa5eNLUEjlJS5z5rXatYuGkCb80LbHcu8AQR8qgAZZaNHCLyo2N+pxPsV7l+ivg== - dependencies: - "@smithy/core" "^2.5.5" - "@smithy/middleware-endpoint" "^3.2.5" - "@smithy/middleware-stack" "^3.0.11" - "@smithy/protocol-http" "^4.1.8" - "@smithy/types" "^3.7.2" - "@smithy/util-stream" "^3.3.2" - tslib "^2.6.2" - -"@smithy/types@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.0.0.tgz#7458c1c4dde3c6cf23221370acf5acd03215de6e" - integrity sha512-aNwIGSOgDOhtTRY/rrn2aeuQeKw/IFrQ998yK5l6Ah853WeWIEmFPs/EO4OpfADEdcK+igWnZytm/oUgkLgUYg== - dependencies: - tslib "^2.6.2" - "@smithy/types@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.2.0.tgz#9dc65767b0ee3d6681704fcc67665d6fc9b6a34e" @@ -5533,13 +4583,6 @@ dependencies: tslib "^2.6.2" -"@smithy/types@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.7.2.tgz#05cb14840ada6f966de1bf9a9c7dd86027343e10" - integrity sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg== - dependencies: - tslib "^2.6.2" - "@smithy/url-parser@^3.0.10", "@smithy/url-parser@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.10.tgz#f389985a79766cff4a99af14979f01a17ce318da" @@ -5549,15 +4592,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/url-parser@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.11.tgz#e5f5ffabfb6230159167cf4cc970705fca6b8b2d" - integrity sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw== - dependencies: - "@smithy/querystring-parser" "^3.0.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/util-base64@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-3.0.0.tgz#f7a9a82adf34e27a72d0719395713edf0e493017" @@ -5615,17 +4649,6 @@ bowser "^2.11.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^3.0.30": - version "3.0.30" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.30.tgz#6c0d95af3f15bef8f1fe3f6217cc4f5ba8df5554" - integrity sha512-nLuGmgfcr0gzm64pqF2UT4SGWVG8UGviAdayDlVzJPNa6Z4lqvpDzdRXmLxtOdEjVlTOEdpZ9dd3ZMMu488mzg== - dependencies: - "@smithy/property-provider" "^3.1.11" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - bowser "^2.11.0" - tslib "^2.6.2" - "@smithy/util-defaults-mode-node@^3.0.26": version "3.0.27" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz#a7248c9d9cb620827ab57ef9d1867bfe8aef42d0" @@ -5639,19 +4662,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^3.0.30": - version "3.0.30" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.30.tgz#33cdb02f90944b9ff221e2f8e0904a63ac1e335f" - integrity sha512-OD63eWoH68vp75mYcfYyuVH+p7Li/mY4sYOROnauDrtObo1cS4uWfsy/zhOTW8F8ZPxQC1ZXZKVxoxvMGUv2Ow== - dependencies: - "@smithy/config-resolver" "^3.0.13" - "@smithy/credential-provider-imds" "^3.2.8" - "@smithy/node-config-provider" "^3.1.12" - "@smithy/property-provider" "^3.1.11" - "@smithy/smithy-client" "^3.5.0" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/util-endpoints@^2.1.5": version "2.1.6" resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz#720cbd1a616ad7c099b77780f0cb0f1f9fc5d2df" @@ -5661,15 +4671,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-endpoints@^2.1.7": - version "2.1.7" - resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz#a088ebfab946a7219dd4763bfced82709894b82d" - integrity sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw== - dependencies: - "@smithy/node-config-provider" "^3.1.12" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/util-hex-encoding@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz#32938b33d5bf2a15796cd3f178a55b4155c535e6" @@ -5685,14 +4686,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-middleware@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-3.0.11.tgz#2ab5c17266b42c225e62befcffb048afa682b5bf" - integrity sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow== - dependencies: - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/util-retry@^3.0.10", "@smithy/util-retry@^3.0.9": version "3.0.10" resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.10.tgz#fc13e1b30e87af0cbecadf29ca83b171e2040440" @@ -5702,15 +4695,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-retry@^3.0.11": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.11.tgz#d267e5ccb290165cee69732547fea17b695a7425" - integrity sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ== - dependencies: - "@smithy/service-error-classification" "^3.0.11" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@smithy/util-stream@^3.3.0", "@smithy/util-stream@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.3.1.tgz#a2636f435637ef90d64df2bb8e71cd63236be112" @@ -5725,20 +4709,6 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/util-stream@^3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.3.2.tgz#daeea26397e8541cf2499ce65bf0b8d528cba421" - integrity sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg== - dependencies: - "@smithy/fetch-http-handler" "^4.1.2" - "@smithy/node-http-handler" "^3.3.2" - "@smithy/types" "^3.7.2" - "@smithy/util-base64" "^3.0.0" - "@smithy/util-buffer-from" "^3.0.0" - "@smithy/util-hex-encoding" "^3.0.0" - "@smithy/util-utf8" "^3.0.0" - tslib "^2.6.2" - "@smithy/util-uri-escape@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-1.1.0.tgz#a8c5edaf19c0efdb9b51661e840549cf600a1808" @@ -5778,15 +4748,6 @@ "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-waiter@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-3.2.0.tgz#1e52f870e77d2e5572025f7606053e6ff00df93d" - integrity sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg== - dependencies: - "@smithy/abort-controller" "^3.1.9" - "@smithy/types" "^3.7.2" - tslib "^2.6.2" - "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" @@ -7096,11 +6057,6 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== -"@types/uuid@^9.0.1": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== - "@types/webidl-conversions@*": version "7.0.0" resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" @@ -8509,14 +7465,6 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -11232,7 +10180,7 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== -events@3.3.0, events@^3.0.0, events@^3.3.0: +events@^3.0.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -12988,7 +11936,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -15812,13 +14760,6 @@ mlly@^1.1.0, mlly@^1.7.1: pkg-types "^1.1.1" ufo "^1.5.3" -mnemonist@0.38.3: - version "0.38.3" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.3.tgz#35ec79c1c1f4357cfda2fe264659c2775ccd7d9d" - integrity sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw== - dependencies: - obliterator "^1.6.1" - modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -16611,11 +15552,6 @@ object.values@^1.1.7: define-properties "^1.2.0" es-abstract "^1.22.1" -obliterator@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" - integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== - omggif@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -19661,14 +18597,6 @@ stoppable@^1.1.0: resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== -stream-browserify@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" - integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== - dependencies: - inherits "~2.0.4" - readable-stream "^3.5.0" - stream-events@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" @@ -19716,16 +18644,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -19817,7 +18736,7 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -19831,13 +18750,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -21585,7 +20497,7 @@ worker-farm@1.7.0: dependencies: errno "~0.1.7" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -21603,15 +20515,6 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 16ec75b272124b7516bd5a50d496099701194333 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 8 Jan 2025 10:28:54 +0000 Subject: [PATCH 57/57] Bump version to 3.2.37 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 9b2cacda12..647c9f202d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.36", + "version": "3.2.37", "npmClient": "yarn", "concurrency": 20, "command": {