From e0be6d0b842a29fdc7694fd497a19bccb6f8f507 Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Thu, 18 Dec 2025 12:26:04 +0000 Subject: [PATCH 1/5] feat: add initial AI service and Amazon Bedrock provider files --- backend/src/entities/ai/ai.service.ts | 0 .../src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 backend/src/entities/ai/ai.service.ts create mode 100644 backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts diff --git a/backend/src/entities/ai/ai.service.ts b/backend/src/entities/ai/ai.service.ts new file mode 100644 index 00000000..e69de29b diff --git a/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts b/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts new file mode 100644 index 00000000..e69de29b From 83ba9b896fa3304d966a224c3accbe72a56f8c29 Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Fri, 19 Dec 2025 14:39:09 +0000 Subject: [PATCH 2/5] feat: add AI module types and provider interface - Created ai-module-types.ts to define TableInformation type with properties for table name, structure, foreign keys, and primary columns. - Introduced ai-provider.interface.ts with IAIProvider interface for generating AI responses. --- backend/package.json | 1 + backend/src/app.module.ts | 1 + .../ai-data-entities/types/ai-module-types.ts | 10 + backend/src/entities/ai/ai.module.ts | 8 +- backend/src/entities/ai/ai.service.ts | 218 +++++++ .../amazon-bedrock/ai-provider.interface.ts | 3 + .../amazon-bedrock.ai.provider.ts | 45 ++ .../use-cases/create-connection.use.case.ts | 3 +- .../shared-jobs/shared-jobs.service.ts | 105 +++- yarn.lock | 557 +++++++++++++++++- 10 files changed, 936 insertions(+), 15 deletions(-) create mode 100644 backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts create mode 100644 backend/src/entities/ai/amazon-bedrock/ai-provider.interface.ts diff --git a/backend/package.json b/backend/package.json index a26f17bd..db8d56e8 100644 --- a/backend/package.json +++ b/backend/package.json @@ -26,6 +26,7 @@ }, "dependencies": { "@amplitude/node": "1.10.2", + "@aws-sdk/client-bedrock-runtime": "^3.954.0", "@aws-sdk/lib-dynamodb": "^3.953.0", "@electric-sql/pglite": "^0.3.14", "@faker-js/faker": "^10.1.0", diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 5f8ca63e..9fb75d1d 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -85,6 +85,7 @@ import { SignInAuditModule } from './entities/user-sign-in-audit/sign-in-audit.m TableCategoriesModule, UserSecretModule, SignInAuditModule, + AIModule, ], controllers: [AppController], providers: [ diff --git a/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts b/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts new file mode 100644 index 00000000..3097cfb4 --- /dev/null +++ b/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts @@ -0,0 +1,10 @@ +import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; +import { PrimaryKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/primary-key.ds.js'; +import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; + +export type TableInformation = { + table_name: string; + structure: Array; + foreignKeys: Array; + primaryColumns: Array; +}; diff --git a/backend/src/entities/ai/ai.module.ts b/backend/src/entities/ai/ai.module.ts index 1e8c9404..49152c38 100644 --- a/backend/src/entities/ai/ai.module.ts +++ b/backend/src/entities/ai/ai.module.ts @@ -1,4 +1,4 @@ -import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; +import { Global, MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthMiddleware } from '../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; @@ -7,7 +7,10 @@ import { LogOutEntity } from '../log-out/log-out.entity.js'; import { UserEntity } from '../user/user.entity.js'; import { RequestInfoFromTableWithAIUseCaseV4 } from './use-cases/request-info-from-table-with-ai-v4.use.case.js'; import { UserAIRequestsControllerV2 } from './user-ai-requests-v2.controller.js'; +import { AiService } from './ai.service.js'; +import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.provider.js'; +@Global() @Module({ imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], providers: [ @@ -19,7 +22,10 @@ import { UserAIRequestsControllerV2 } from './user-ai-requests-v2.controller.js' provide: UseCaseType.REQUEST_INFO_FROM_TABLE_WITH_AI_V2, useClass: RequestInfoFromTableWithAIUseCaseV4, }, + AmazonBedrockAiProvider, + AiService, ], + exports: [AiService, AmazonBedrockAiProvider], controllers: [UserAIRequestsControllerV2], }) export class AIModule implements NestModule { diff --git a/backend/src/entities/ai/ai.service.ts b/backend/src/entities/ai/ai.service.ts index e69de29b..ba1e2b6c 100644 --- a/backend/src/entities/ai/ai.service.ts +++ b/backend/src/entities/ai/ai.service.ts @@ -0,0 +1,218 @@ +import { Injectable } from '@nestjs/common'; +import { TableSettingsEntity } from '../table-settings/table-settings.entity.js'; +import { TableWidgetEntity } from '../widget/table-widget.entity.js'; +import { TableInformation } from './ai-data-entities/types/ai-module-types.js'; +import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.provider.js'; +import { QueryOrderingEnum } from '../../enums/query-ordering.enum.js'; +import { WidgetTypeEnum } from '../../enums/widget-type.enum.js'; +import { checkFieldAutoincrement } from '../../helpers/check-field-autoincrement.js'; + +interface AIGeneratedTableSettings { + table_name: string; + display_name: string; + list_fields: string[]; + ordering_field: string | null; + ordering: 'ASC' | 'DESC'; + search_fields: string[]; + readonly_fields: string[]; + columns_view: string[]; + widgets: Array<{ + field_name: string; + widget_type: string; + name: string; + description: string; + }>; +} + +interface AIResponse { + tables: AIGeneratedTableSettings[]; +} + +@Injectable() +export class AiService { + constructor(protected readonly aiProvider: AmazonBedrockAiProvider) {} + + public async generateNewTableSettingsWithAI( + tablesInformation: Array, + ): Promise> { + const prompt = this.buildPrompt(tablesInformation); + const aiResponse = await this.aiProvider.generateResponse(prompt); + const parsedResponse = this.parseAIResponse(aiResponse); + return this.buildTableSettingsEntities(parsedResponse, tablesInformation); + } + + private buildPrompt(tablesInformation: Array): string { + const widgetTypes = Object.values(WidgetTypeEnum).join(', '); + + const tablesDescription = tablesInformation + .map((table) => { + const columns = table.structure + .map( + (col) => + ` - ${col.column_name}: ${col.data_type}${col.allow_null ? ' (nullable)' : ''}${checkFieldAutoincrement(col.column_default, col.extra) ? ' (auto_increment)' : ''}`, + ) + .join('\n'); + const primaryKeys = table.primaryColumns.map((pk) => pk.column_name).join(', '); + const foreignKeys = table.foreignKeys + .map((fk) => ` - ${fk.column_name} -> ${fk.referenced_table_name}.${fk.referenced_column_name}`) + .join('\n'); + + return ` +Table: ${table.table_name} + Primary Keys: ${primaryKeys || 'none'} + Columns: +${columns} + Foreign Keys: +${foreignKeys || ' none'}`; + }) + .join('\n\n'); + + return `You are a database administration assistant. Analyze the following database tables and generate optimal settings for displaying and managing them in a web admin panel. + +For each table, provide: +1. display_name: A human-readable name for the table +2. list_fields: Columns to display in the table list view (most important columns first, max 5-7 columns) +3. ordering_field: The best column to sort by default (usually created_at, id, or a timestamp) +4. ordering: ASC or DESC +5. search_fields: Columns that should be searchable +6. readonly_fields: Columns that should not be editable (like auto_increment, timestamps) +7. columns_view: All columns in preferred display order +8. widgets: For each column, suggest the best widget type from: ${widgetTypes} + +Available widget types and when to use them: +- Password: for password fields +- Boolean: for boolean/bit columns +- Date: for date columns +- Time: for time-only columns +- DateTime: for datetime/timestamp columns +- JSON: for JSON/JSONB columns +- Textarea: for long text fields (description, content, etc.) +- String: for short text fields (name, title, etc.) +- Readonly: for auto-generated fields +- Number: for numeric columns +- Select: for columns with limited options +- UUID: for UUID columns +- Enum: for enum columns +- Foreign_key: for foreign key columns +- File: for file path columns +- Image: for image URL columns +- URL: for URL columns +- Code: for code snippets +- Phone: for phone number columns +- Country: for country columns +- Color: for color columns (hex values) +- Range: for range values +- Timezone: for timezone columns + +Database tables to analyze: +${tablesDescription} + +Respond ONLY with valid JSON in this exact format (no markdown, no explanations): +{ + "tables": [ + { + "table_name": "table_name", + "display_name": "Human Readable Name", + "list_fields": ["col1", "col2"], + "ordering_field": "created_at", + "ordering": "DESC", + "search_fields": ["name", "email"], + "readonly_fields": ["id", "created_at"], + "columns_view": ["id", "name", "email", "created_at"], + "widgets": [ + { + "field_name": "column_name", + "widget_type": "String", + "name": "Column Display Name", + "description": "Description of what this column contains" + } + ] + } + ] +}`; + } + + private parseAIResponse(aiResponse: string): AIResponse { + let cleanedResponse = aiResponse.trim(); + if (cleanedResponse.startsWith('```json')) { + cleanedResponse = cleanedResponse.slice(7); + } else if (cleanedResponse.startsWith('```')) { + cleanedResponse = cleanedResponse.slice(3); + } + if (cleanedResponse.endsWith('```')) { + cleanedResponse = cleanedResponse.slice(0, -3); + } + cleanedResponse = cleanedResponse.trim(); + + try { + return JSON.parse(cleanedResponse) as AIResponse; + } catch (error) { + throw new Error(`Failed to parse AI response: ${error.message}`); + } + } + + private buildTableSettingsEntities( + aiResponse: AIResponse, + tablesInformation: Array, + ): Array { + return aiResponse.tables.map((tableSettings) => { + const tableInfo = tablesInformation.find((t) => t.table_name === tableSettings.table_name); + const validColumnNames = tableInfo?.structure.map((col) => col.column_name) || []; + + const settings = new TableSettingsEntity(); + settings.table_name = tableSettings.table_name; + settings.display_name = tableSettings.display_name; + settings.list_fields = this.filterValidColumns(tableSettings.list_fields, validColumnNames); + settings.ordering_field = tableSettings.ordering_field; + settings.ordering = tableSettings.ordering === 'DESC' ? QueryOrderingEnum.DESC : QueryOrderingEnum.ASC; + settings.search_fields = this.filterValidColumns(tableSettings.search_fields, validColumnNames); + settings.readonly_fields = this.filterValidColumns(tableSettings.readonly_fields, validColumnNames); + settings.columns_view = this.filterValidColumns(tableSettings.columns_view, validColumnNames); + settings.table_widgets = tableSettings.widgets + .filter((w) => validColumnNames.includes(w.field_name)) + .map((widgetData) => { + const widget = new TableWidgetEntity(); + widget.field_name = widgetData.field_name; + widget.widget_type = this.mapWidgetType(widgetData.widget_type); + widget.name = widgetData.name; + widget.description = widgetData.description; + return widget; + }); + + return settings; + }); + } + + private filterValidColumns(columns: string[], validColumnNames: string[]): string[] { + return columns?.filter((col) => validColumnNames.includes(col)) || []; + } + + private mapWidgetType(widgetType: string): WidgetTypeEnum | undefined { + const widgetTypeMap = new Map([ + ['Password', WidgetTypeEnum.Password], + ['Boolean', WidgetTypeEnum.Boolean], + ['Date', WidgetTypeEnum.Date], + ['Time', WidgetTypeEnum.Time], + ['DateTime', WidgetTypeEnum.DateTime], + ['JSON', WidgetTypeEnum.JSON], + ['Textarea', WidgetTypeEnum.Textarea], + ['String', WidgetTypeEnum.String], + ['Readonly', WidgetTypeEnum.Readonly], + ['Number', WidgetTypeEnum.Number], + ['Select', WidgetTypeEnum.Select], + ['UUID', WidgetTypeEnum.UUID], + ['Enum', WidgetTypeEnum.Enum], + ['Foreign_key', WidgetTypeEnum.Foreign_key], + ['File', WidgetTypeEnum.File], + ['Image', WidgetTypeEnum.Image], + ['URL', WidgetTypeEnum.URL], + ['Code', WidgetTypeEnum.Code], + ['Phone', WidgetTypeEnum.Phone], + ['Country', WidgetTypeEnum.Country], + ['Color', WidgetTypeEnum.Color], + ['Range', WidgetTypeEnum.Range], + ['Timezone', WidgetTypeEnum.Timezone], + ]); + return widgetTypeMap.get(widgetType); + } +} diff --git a/backend/src/entities/ai/amazon-bedrock/ai-provider.interface.ts b/backend/src/entities/ai/amazon-bedrock/ai-provider.interface.ts new file mode 100644 index 00000000..bfe99ab1 --- /dev/null +++ b/backend/src/entities/ai/amazon-bedrock/ai-provider.interface.ts @@ -0,0 +1,3 @@ +export interface IAIProvider { + generateResponse(prompt: string): Promise; +} diff --git a/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts b/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts index e69de29b..cbdf9bbc 100644 --- a/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts +++ b/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@nestjs/common'; +import { BedrockRuntimeClient, ConverseCommand } from '@aws-sdk/client-bedrock-runtime'; +import { IAIProvider } from './ai-provider.interface.js'; + +@Injectable() +export class AmazonBedrockAiProvider implements IAIProvider { + private readonly bedrockRuntimeClient: BedrockRuntimeClient; + private readonly modelId: string = 'global.anthropic.claude-sonnet-4-20250514-v1:0'; + private readonly temperature: number = 0.7; + private readonly maxTokens: number = 1024; + private readonly region: string = 'us-west-2'; + private readonly topP: number = 0.9; + + constructor() { + this.bedrockRuntimeClient = new BedrockRuntimeClient({ + region: this.region, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, + }); + } + public async generateResponse(prompt: string): Promise { + const conversation = [ + { + role: 'user' as const, + content: [{ text: prompt }], + }, + ]; + + const command = new ConverseCommand({ + modelId: this.modelId, + messages: conversation, + inferenceConfig: { maxTokens: this.maxTokens, temperature: this.temperature, topP: this.topP }, + }); + try { + const response = await this.bedrockRuntimeClient.send(command); + const responseText = response.output.message?.content[0].text; + return responseText || 'No response generated.'; + } catch (error) { + console.error('Error generating AI response:', error); + throw new Error('Failed to generate AI response.'); + } + } +} diff --git a/backend/src/entities/connection/use-cases/create-connection.use.case.ts b/backend/src/entities/connection/use-cases/create-connection.use.case.ts index 0f7e7e34..a146cd58 100644 --- a/backend/src/entities/connection/use-cases/create-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/create-connection.use.case.ts @@ -115,7 +115,8 @@ export class CreateConnectionUseCase throw e; } finally { if (isConnectionTestedSuccessfully && !isConnectionTypeAgent(connectionCopy.type)) { - await this.sharedJobsService.scanDatabaseAndCreateWidgets(connectionCopy); + // await this.sharedJobsService.scanDatabaseAndCreateWidgets(connectionCopy); + await this.sharedJobsService.scanDatabaseAndCreateSettingsAndWidgetsWithAI(connectionCopy); } } } diff --git a/backend/src/entities/shared-jobs/shared-jobs.service.ts b/backend/src/entities/shared-jobs/shared-jobs.service.ts index 547d7d5f..7c100fa7 100644 --- a/backend/src/entities/shared-jobs/shared-jobs.service.ts +++ b/backend/src/entities/shared-jobs/shared-jobs.service.ts @@ -3,6 +3,7 @@ import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-acce import { TableDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table.ds.js'; import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { buildValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/validate-table-settings-ds.builder.js'; import * as Sentry from '@sentry/node'; import PQueue from 'p-queue'; import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js'; @@ -13,13 +14,98 @@ import { ConnectionEntity } from '../connection/connection.entity.js'; import { buildEmptyTableSettings } from '../table-settings/utils/build-empty-table-settings.js'; import { buildNewTableSettingsEntity } from '../table-settings/utils/build-new-table-settings-entity.js'; import { TableWidgetEntity } from '../widget/table-widget.entity.js'; +import { AiService } from '../ai/ai.service.js'; +import { TableSettingsEntity } from '../table-settings/table-settings.entity.js'; +import { isTest } from '../../helpers/app/is-test.js'; + @Injectable() export class SharedJobsService { constructor( @Inject(BaseType.GLOBAL_DB_CONTEXT) protected _dbContext: IGlobalDatabaseContext, + private readonly aiService: AiService, ) {} + public async scanDatabaseAndCreateSettingsAndWidgetsWithAI(connection: ConnectionEntity): Promise { + if (!connection || isTest()) { + return; + } + try { + const dao = getDataAccessObject(connection); + const tables: Array = await dao.getTablesFromDB(); + const queue = new PQueue({ concurrency: 4 }); + const tablesInformation = await Promise.all( + tables.map((table) => + queue.add(async () => { + const structure = await dao.getTableStructure(table.tableName, null); + const primaryColumns = await dao.getTablePrimaryColumns(table.tableName, null); + const foreignKeys = await dao.getTableForeignKeys(table.tableName, null); + return { + table_name: table.tableName, + structure, + primaryColumns, + foreignKeys, + }; + }), + ), + ); + + const generatedTableSettings = await this.aiService.generateNewTableSettingsWithAI(tablesInformation); + + const widgetsByTable = new Map>(); + for (const setting of generatedTableSettings) { + if (setting.table_widgets && setting.table_widgets.length > 0) { + widgetsByTable.set(setting.table_name, setting.table_widgets); + } + } + + const normalizedSettings = this.normalizeAISettings(generatedTableSettings, connection); + + const validationQueue = new PQueue({ concurrency: 4 }); + const validatedSettings = await Promise.all( + normalizedSettings.map((setting) => + validationQueue.add(async () => { + const validateSettingsDS = buildValidateTableSettingsDS(setting); + const errors = await dao.validateSettings(validateSettingsDS, setting.table_name, undefined); + if (errors.length > 0) { + console.error(`Validation errors for table "${setting.table_name}":`, errors); + return null; + } + return setting; + }), + ), + ); + + const settingsToSave = validatedSettings.filter((setting) => setting !== null); + if (settingsToSave.length > 0) { + const savedSettings = await this._dbContext.tableSettingsRepository.save(settingsToSave); + const widgetsToSave: Array = []; + for (const savedSetting of savedSettings) { + const widgets = widgetsByTable.get(savedSetting.table_name); + if (widgets && widgets.length > 0) { + for (const widget of widgets) { + const widgetEntity = new TableWidgetEntity(); + widgetEntity.field_name = widget.field_name; + widgetEntity.widget_type = widget.widget_type; + widgetEntity.widget_params = widget.widget_params || null; + widgetEntity.widget_options = widget.widget_options || null; + widgetEntity.name = widget.name || null; + widgetEntity.description = widget.description || null; + widgetEntity.settings = savedSetting; + widgetsToSave.push(widgetEntity); + } + } + } + + if (widgetsToSave.length > 0) { + await this._dbContext.tableWidgetsRepository.save(widgetsToSave); + } + } + } catch (error) { + Sentry.captureException(error); + } + } + public async scanDatabaseAndCreateWidgets(connection: ConnectionEntity): Promise { if (!connection) { return; @@ -46,6 +132,18 @@ export class SharedJobsService { } } + private normalizeAISettings( + aiSettings: Array, + connection: ConnectionEntity, + ): Array { + aiSettings.forEach((setting) => { + delete setting.id; + setting.connection_id = connection; + delete setting.table_widgets; + }); + return aiSettings; + } + private async scanTableAndCreateWidgets( tableName: string, connection: ConnectionEntity, @@ -279,13 +377,6 @@ export class SharedJobsService { return urlRegex.test(value) && ValidationHelper.isValidUrl(value); } - private isValueJSON(value: unknown): boolean { - if (typeof value !== 'string') { - return false; - } - return ValidationHelper.isValidJSON(value); - } - private isValueCountryCode(value: unknown): boolean { if (typeof value !== 'string') { return false; diff --git a/yarn.lock b/yarn.lock index c3f30d1e..34a5b066 100644 --- a/yarn.lock +++ b/yarn.lock @@ -153,6 +153,17 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/crc32@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/crc32@npm:5.2.0" + dependencies: + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^2.6.2 + checksum: 1ddf7ec3fccf106205ff2476d90ae1d6625eabd47752f689c761b71e41fe451962b7a1c9ed25fe54e17dd747a62fbf4de06030fe56fe625f95285f6f70b96c57 + languageName: node + linkType: hard + "@aws-crypto/sha256-browser@npm:5.2.0": version: 5.2.0 resolution: "@aws-crypto/sha256-browser@npm:5.2.0" @@ -199,6 +210,61 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-bedrock-runtime@npm:^3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/client-bedrock-runtime@npm:3.954.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.954.0 + "@aws-sdk/credential-provider-node": 3.954.0 + "@aws-sdk/eventstream-handler-node": 3.953.0 + "@aws-sdk/middleware-eventstream": 3.953.0 + "@aws-sdk/middleware-host-header": 3.953.0 + "@aws-sdk/middleware-logger": 3.953.0 + "@aws-sdk/middleware-recursion-detection": 3.953.0 + "@aws-sdk/middleware-user-agent": 3.954.0 + "@aws-sdk/middleware-websocket": 3.953.0 + "@aws-sdk/region-config-resolver": 3.953.0 + "@aws-sdk/token-providers": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@aws-sdk/util-endpoints": 3.953.0 + "@aws-sdk/util-user-agent-browser": 3.953.0 + "@aws-sdk/util-user-agent-node": 3.954.0 + "@smithy/config-resolver": ^4.4.4 + "@smithy/core": ^3.19.0 + "@smithy/eventstream-serde-browser": ^4.2.6 + "@smithy/eventstream-serde-config-resolver": ^4.3.6 + "@smithy/eventstream-serde-node": ^4.2.6 + "@smithy/fetch-http-handler": ^5.3.7 + "@smithy/hash-node": ^4.2.6 + "@smithy/invalid-dependency": ^4.2.6 + "@smithy/middleware-content-length": ^4.2.6 + "@smithy/middleware-endpoint": ^4.4.0 + "@smithy/middleware-retry": ^4.4.16 + "@smithy/middleware-serde": ^4.2.7 + "@smithy/middleware-stack": ^4.2.6 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/node-http-handler": ^4.4.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/smithy-client": ^4.10.1 + "@smithy/types": ^4.10.0 + "@smithy/url-parser": ^4.2.6 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.15 + "@smithy/util-defaults-mode-node": ^4.2.18 + "@smithy/util-endpoints": ^3.2.6 + "@smithy/util-middleware": ^4.2.6 + "@smithy/util-retry": ^4.2.6 + "@smithy/util-stream": ^4.5.7 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 6d73e6bbdab5149e12325868ed222e4b30f9e137791ffb157699603d5390f2ee536b67a08596d0cc4359f0b53cc4b1ba8d6422041b6ea21ed602ee1d04b97491 + languageName: node + linkType: hard + "@aws-sdk/client-dynamodb@npm:^3.952.0": version: 3.952.0 resolution: "@aws-sdk/client-dynamodb@npm:3.952.0" @@ -389,6 +455,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-sso@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/client-sso@npm:3.954.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.954.0 + "@aws-sdk/middleware-host-header": 3.953.0 + "@aws-sdk/middleware-logger": 3.953.0 + "@aws-sdk/middleware-recursion-detection": 3.953.0 + "@aws-sdk/middleware-user-agent": 3.954.0 + "@aws-sdk/region-config-resolver": 3.953.0 + "@aws-sdk/types": 3.953.0 + "@aws-sdk/util-endpoints": 3.953.0 + "@aws-sdk/util-user-agent-browser": 3.953.0 + "@aws-sdk/util-user-agent-node": 3.954.0 + "@smithy/config-resolver": ^4.4.4 + "@smithy/core": ^3.19.0 + "@smithy/fetch-http-handler": ^5.3.7 + "@smithy/hash-node": ^4.2.6 + "@smithy/invalid-dependency": ^4.2.6 + "@smithy/middleware-content-length": ^4.2.6 + "@smithy/middleware-endpoint": ^4.4.0 + "@smithy/middleware-retry": ^4.4.16 + "@smithy/middleware-serde": ^4.2.7 + "@smithy/middleware-stack": ^4.2.6 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/node-http-handler": ^4.4.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/smithy-client": ^4.10.1 + "@smithy/types": ^4.10.0 + "@smithy/url-parser": ^4.2.6 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.15 + "@smithy/util-defaults-mode-node": ^4.2.18 + "@smithy/util-endpoints": ^3.2.6 + "@smithy/util-middleware": ^4.2.6 + "@smithy/util-retry": ^4.2.6 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 0ba6bb9a6fb26c0f0686bf76792f3d7fcbb6defade88f05872737388310115f417eae14e22db6ed1c6e5ef25f6b8bf78f4133cdd8766a9dba752220179c3b33d + languageName: node + linkType: hard + "@aws-sdk/core@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/core@npm:3.926.0" @@ -452,6 +564,27 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/core@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/core@npm:3.954.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@aws-sdk/xml-builder": 3.953.0 + "@smithy/core": ^3.19.0 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/property-provider": ^4.2.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/signature-v4": ^5.3.6 + "@smithy/smithy-client": ^4.10.1 + "@smithy/types": ^4.10.0 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-middleware": ^4.2.6 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: 5928daf164b4fc1db7f1a5b831d0c12229421124253163d4cf104b6e084650465c450fb9c57b3ff92dd5846394f6dca6e4d0ca469cc8e89128e824b0a2d14994 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-env@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-env@npm:3.926.0" @@ -478,6 +611,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-env@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: d8fc24b85ce8f83189862cacdbfc3a0559dc8217c8e837c500c86579c73a1b4266bd83efb262ea44bd523941d9d2ed283d2d294c1a679fd5ec66fa153c7657ea + languageName: node + linkType: hard + "@aws-sdk/credential-provider-http@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-http@npm:3.926.0" @@ -514,6 +660,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-http@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/fetch-http-handler": ^5.3.7 + "@smithy/node-http-handler": ^4.4.6 + "@smithy/property-provider": ^4.2.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/smithy-client": ^4.10.1 + "@smithy/types": ^4.10.0 + "@smithy/util-stream": ^4.5.7 + tslib: ^2.6.2 + checksum: 9c6afaf1c069252f5077be380dc5594addc3cb5e39d3a4905802c14f6c0c543893ddad7269706260e7ed1f20329195139e3ecc6343f8225c82adb371175b61e9 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-ini@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-ini@npm:3.926.0" @@ -557,6 +721,28 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/credential-provider-env": 3.954.0 + "@aws-sdk/credential-provider-http": 3.954.0 + "@aws-sdk/credential-provider-login": 3.954.0 + "@aws-sdk/credential-provider-process": 3.954.0 + "@aws-sdk/credential-provider-sso": 3.954.0 + "@aws-sdk/credential-provider-web-identity": 3.954.0 + "@aws-sdk/nested-clients": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/credential-provider-imds": ^4.2.6 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 5373119e4618f2004a866124549153333f17205d8ebfee96673874809ca8aebcc014cd6ade36c1b969e68dc165925631995ed6e3fbc3a19a1eb6176718f8790c + languageName: node + linkType: hard + "@aws-sdk/credential-provider-login@npm:3.952.0": version: 3.952.0 resolution: "@aws-sdk/credential-provider-login@npm:3.952.0" @@ -573,6 +759,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-login@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-login@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/nested-clients": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: ca73f9202d17a29b4dfa760c9ec542103aed12e16d75b8161ae2328f8f2c49af5a4795099a376951604e1b61a0db377b2157d7db2db671e419befb4354dd45a4 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-node@npm:3.926.0" @@ -613,6 +815,26 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.954.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.954.0 + "@aws-sdk/credential-provider-http": 3.954.0 + "@aws-sdk/credential-provider-ini": 3.954.0 + "@aws-sdk/credential-provider-process": 3.954.0 + "@aws-sdk/credential-provider-sso": 3.954.0 + "@aws-sdk/credential-provider-web-identity": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/credential-provider-imds": ^4.2.6 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 882e844ea276162428f1f1e1d09296f08c393052516db9e0518a44a3e70dbbefd76281a2b3d76987535df5ce481ef778d85b3157e9a253963cf888abedf1bc43 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-process@npm:3.926.0" @@ -641,6 +863,20 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-process@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: b3ae10b9b8e3ed6a9c5cc19aef61bb9346ad655b1d9d63cce18e0d990a98144aa65e38b5783bdb069cb8b3ff71fb8519bdf2d7bec2ece5ac6bba9fc7b9088251 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-sso@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-sso@npm:3.926.0" @@ -673,6 +909,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.954.0" + dependencies: + "@aws-sdk/client-sso": 3.954.0 + "@aws-sdk/core": 3.954.0 + "@aws-sdk/token-providers": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 9293e9114577f28f5555a42ce92a8ab1cbbce707e6fa0889e8e15150a4bf8d96aeacb74cf1f30b04c5025e685543aee65c770a7d0849928e583ad35aa9b36964 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.926.0" @@ -703,6 +955,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/nested-clients": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: c55541f6bd79e88c4711839160e275a54beaa2337d6351c1e73f471d878a89e06dde7ce49ab2e7762a3c3f4c623e6fa0e2ffddf29bab0dfe593aaff2af909cd7 + languageName: node + linkType: hard + "@aws-sdk/dynamodb-codec@npm:3.947.0": version: 3.947.0 resolution: "@aws-sdk/dynamodb-codec@npm:3.947.0" @@ -729,6 +996,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/eventstream-handler-node@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/eventstream-handler-node@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/eventstream-codec": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: f4b03a614db1e9a9a14bb751867e4327aca65f6e86c9a43ba8f775417f07cdf81248c410a94ae00c42703198b94434799d85ac9b50fb6732799180cf61c8092f + languageName: node + linkType: hard + "@aws-sdk/lib-dynamodb@npm:^3.952.0, @aws-sdk/lib-dynamodb@npm:^3.953.0": version: 3.953.0 resolution: "@aws-sdk/lib-dynamodb@npm:3.953.0" @@ -759,6 +1038,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-eventstream@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/middleware-eventstream@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/protocol-http": ^5.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: ee8ac296508c2c965a42e0a7e31fc4da8339e1b2736b8baf2dac99d51fcc1d62bd14a1e63ec8b35c5a44885ae1627106044697423d31549c96207dbdeb77a100 + languageName: node + linkType: hard + "@aws-sdk/middleware-host-header@npm:3.922.0": version: 3.922.0 resolution: "@aws-sdk/middleware-host-header@npm:3.922.0" @@ -783,6 +1074,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-host-header@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/protocol-http": ^5.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 73b4643e7d2d3312cb00bd81d286425fd9ca3b17b9742109bd56142a8f4b7ef5744bde7e81da79190f0076f8eefb4a2b2132078a26bc6c4731e6e93b2613f67f + languageName: node + linkType: hard + "@aws-sdk/middleware-logger@npm:3.922.0": version: 3.922.0 resolution: "@aws-sdk/middleware-logger@npm:3.922.0" @@ -805,6 +1108,17 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-logger@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/middleware-logger@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: db026a3b53c31708f7f1eb822da04dfcd5adb767692528be764ca59c7108fc20e3b1f3de0ba3e7c4bde80fab6b1256b1ad0ccb030752bcf5e5da16d473f75aac + languageName: node + linkType: hard + "@aws-sdk/middleware-recursion-detection@npm:3.922.0": version: 3.922.0 resolution: "@aws-sdk/middleware-recursion-detection@npm:3.922.0" @@ -831,6 +1145,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-recursion-detection@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@aws/lambda-invoke-store": ^0.2.2 + "@smithy/protocol-http": ^5.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 66ea964c1a8be3b847851bd3bec156a5c21e6ad2d8c9a28b163a103518cdd86d96a72ed3121c443aa6e6d7131a573163741be4fc4f26ed0d2a4c1b7fcd264259 + languageName: node + linkType: hard + "@aws-sdk/middleware-sdk-s3@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.926.0" @@ -883,6 +1210,39 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@aws-sdk/util-endpoints": 3.953.0 + "@smithy/core": ^3.19.0 + "@smithy/protocol-http": ^5.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 26a18c3ffececa22b64bb9a215f77bff1a7232324e562d87826d9a7651d5e8f2aa67745448afbe8cc0146eb61456037b83cfe36721b3ee45fc837ad475b89db5 + languageName: node + linkType: hard + +"@aws-sdk/middleware-websocket@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/middleware-websocket@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@aws-sdk/util-format-url": 3.953.0 + "@smithy/eventstream-codec": ^4.2.6 + "@smithy/eventstream-serde-browser": ^4.2.6 + "@smithy/fetch-http-handler": ^5.3.7 + "@smithy/protocol-http": ^5.3.6 + "@smithy/signature-v4": ^5.3.6 + "@smithy/types": ^4.10.0 + "@smithy/util-hex-encoding": ^4.2.0 + tslib: ^2.6.2 + checksum: 6ff4c61d76eebf132190b107d13cd67a30cf88db97a7e3c9f24c0e9049efb12968fedc29fe45c77930576912aeb8cfb9c44931a003ee2197f69bb4c05a21e507 + languageName: node + linkType: hard + "@aws-sdk/nested-clients@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/nested-clients@npm:3.926.0" @@ -975,6 +1335,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/nested-clients@npm:3.954.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.954.0 + "@aws-sdk/middleware-host-header": 3.953.0 + "@aws-sdk/middleware-logger": 3.953.0 + "@aws-sdk/middleware-recursion-detection": 3.953.0 + "@aws-sdk/middleware-user-agent": 3.954.0 + "@aws-sdk/region-config-resolver": 3.953.0 + "@aws-sdk/types": 3.953.0 + "@aws-sdk/util-endpoints": 3.953.0 + "@aws-sdk/util-user-agent-browser": 3.953.0 + "@aws-sdk/util-user-agent-node": 3.954.0 + "@smithy/config-resolver": ^4.4.4 + "@smithy/core": ^3.19.0 + "@smithy/fetch-http-handler": ^5.3.7 + "@smithy/hash-node": ^4.2.6 + "@smithy/invalid-dependency": ^4.2.6 + "@smithy/middleware-content-length": ^4.2.6 + "@smithy/middleware-endpoint": ^4.4.0 + "@smithy/middleware-retry": ^4.4.16 + "@smithy/middleware-serde": ^4.2.7 + "@smithy/middleware-stack": ^4.2.6 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/node-http-handler": ^4.4.6 + "@smithy/protocol-http": ^5.3.6 + "@smithy/smithy-client": ^4.10.1 + "@smithy/types": ^4.10.0 + "@smithy/url-parser": ^4.2.6 + "@smithy/util-base64": ^4.3.0 + "@smithy/util-body-length-browser": ^4.2.0 + "@smithy/util-body-length-node": ^4.2.1 + "@smithy/util-defaults-mode-browser": ^4.3.15 + "@smithy/util-defaults-mode-node": ^4.2.18 + "@smithy/util-endpoints": ^3.2.6 + "@smithy/util-middleware": ^4.2.6 + "@smithy/util-retry": ^4.2.6 + "@smithy/util-utf8": ^4.2.0 + tslib: ^2.6.2 + checksum: f8b4e1cb5f37de5b44e43ad24ae8792c9b9813da61bc7c26b31ca3456ea0c0bc5a4d72283079fc755f155e8bb437bea8837b21ed17bcebc7ee42f2c767716e8e + languageName: node + linkType: hard + "@aws-sdk/region-config-resolver@npm:3.925.0": version: 3.925.0 resolution: "@aws-sdk/region-config-resolver@npm:3.925.0" @@ -1001,6 +1407,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/region-config-resolver@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/config-resolver": ^4.4.4 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: e4ffd77e6d639df8b0f6f3c4737f5edb48748f6cc22c7f7787be0354567ac7bd4d70f1691ac13a551ba1160da46ccee0edb97a1aa64aa224b11cc1d5bb2d329d + languageName: node + linkType: hard + "@aws-sdk/signature-v4-multi-region@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/signature-v4-multi-region@npm:3.926.0" @@ -1045,6 +1464,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/token-providers@npm:3.954.0" + dependencies: + "@aws-sdk/core": 3.954.0 + "@aws-sdk/nested-clients": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/property-provider": ^4.2.6 + "@smithy/shared-ini-file-loader": ^4.4.1 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: b2419ff9acf7427961baf65fc45061fa820034e42a820532f11116551af014ed8973944d82774848066b740ed237818352a6615d599802be4bbc785d4303ead2 + languageName: node + linkType: hard + "@aws-sdk/types@npm:3.922.0": version: 3.922.0 resolution: "@aws-sdk/types@npm:3.922.0" @@ -1121,6 +1555,31 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/util-endpoints@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/types": ^4.10.0 + "@smithy/url-parser": ^4.2.6 + "@smithy/util-endpoints": ^3.2.6 + tslib: ^2.6.2 + checksum: 073d3798955b89a021086a5995577a10f3a38bd6e893f4d065205dfbf388e9811b9108a42cb2f6c4f97aa5b8c061acf6f619045dad15e023abf4804a3d0e1770 + languageName: node + linkType: hard + +"@aws-sdk/util-format-url@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/util-format-url@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/querystring-builder": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 582871f4685183c1ff89703bb2fb1e7dfd5d51147344a0680f943f22b11e41372f0ceffdd33a97603dfdeb81fab418a508633dc75093ceebd79fc0a828ac3307 + languageName: node + linkType: hard + "@aws-sdk/util-locate-window@npm:^3.0.0": version: 3.893.0 resolution: "@aws-sdk/util-locate-window@npm:3.893.0" @@ -1154,6 +1613,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-browser@npm:3.953.0": + version: 3.953.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.953.0" + dependencies: + "@aws-sdk/types": 3.953.0 + "@smithy/types": ^4.10.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 4ac0510791921ef7545bcaf8feee6e92fb222d19968556c816ea71854f78d58986a711abf27a345fa110bf05268734f9d49e8f0e322d64c59ef7a0e5b3ad50d1 + languageName: node + linkType: hard + "@aws-sdk/util-user-agent-node@npm:3.926.0": version: 3.926.0 resolution: "@aws-sdk/util-user-agent-node@npm:3.926.0" @@ -1190,6 +1661,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:3.954.0": + version: 3.954.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.954.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.954.0 + "@aws-sdk/types": 3.953.0 + "@smithy/node-config-provider": ^4.3.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: faf24220fa6f1065b6169c352135983ff6dbd0f8e704a8da08a18ad552274076a038d7ce1d05163e7327cac825a261da62031865379527d372d113943f80a1d9 + languageName: node + linkType: hard + "@aws-sdk/xml-builder@npm:3.921.0": version: 3.921.0 resolution: "@aws-sdk/xml-builder@npm:3.921.0" @@ -3826,6 +4315,61 @@ __metadata: languageName: node linkType: hard +"@smithy/eventstream-codec@npm:^4.2.6": + version: 4.2.6 + resolution: "@smithy/eventstream-codec@npm:4.2.6" + dependencies: + "@aws-crypto/crc32": 5.2.0 + "@smithy/types": ^4.10.0 + "@smithy/util-hex-encoding": ^4.2.0 + tslib: ^2.6.2 + checksum: 70431c2a6308bd37531ccdaa4f95412e71b405868a85c7eb26f4d06a409579fa97ebe9ea98a14c5ea8e9c387309e56febc4d7185c17d7c24b71f27e582c13555 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-browser@npm:^4.2.6": + version: 4.2.6 + resolution: "@smithy/eventstream-serde-browser@npm:4.2.6" + dependencies: + "@smithy/eventstream-serde-universal": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 4ef06e570d1a9e3099884af7b45a9112a38c84c5d8c78e590bf1cf96d10057084e99fc3fe0b74a84a004b8f1ffed11dd77005a1cc42c46de5975b5337409a3da + languageName: node + linkType: hard + +"@smithy/eventstream-serde-config-resolver@npm:^4.3.6": + version: 4.3.6 + resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.6" + dependencies: + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 94f980427e55c48431e55616b50c3de2a96d489d3e260e357dc3996018e01078c55730f614a477c99f5ba43231f5442610c64d1c2c36a99eedeaf3ef59cc0d17 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-node@npm:^4.2.6": + version: 4.2.6 + resolution: "@smithy/eventstream-serde-node@npm:4.2.6" + dependencies: + "@smithy/eventstream-serde-universal": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 928f9fe5e0caec0fcfc6003f31658ee4eaee3e1e4cfb930489a934a249c2dc32ee5f819dc52c438f996daf7613b0c99152e4c5f3dc6bdf05f236c4310f001a6e + languageName: node + linkType: hard + +"@smithy/eventstream-serde-universal@npm:^4.2.6": + version: 4.2.6 + resolution: "@smithy/eventstream-serde-universal@npm:4.2.6" + dependencies: + "@smithy/eventstream-codec": ^4.2.6 + "@smithy/types": ^4.10.0 + tslib: ^2.6.2 + checksum: 3296dbc36c318a456347e422a3f7c3fae87c8f8016e8866811b9f6ab921433223b54051f32d051132ad38521c38dce454ff4f828367dbaca40411ef3e3b6490f + languageName: node + linkType: hard + "@smithy/fetch-http-handler@npm:^5.3.5, @smithy/fetch-http-handler@npm:^5.3.6, @smithy/fetch-http-handler@npm:^5.3.7": version: 5.3.7 resolution: "@smithy/fetch-http-handler@npm:5.3.7" @@ -3839,7 +4383,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^4.2.4, @smithy/hash-node@npm:^4.2.5": +"@smithy/hash-node@npm:^4.2.4, @smithy/hash-node@npm:^4.2.5, @smithy/hash-node@npm:^4.2.6": version: 4.2.6 resolution: "@smithy/hash-node@npm:4.2.6" dependencies: @@ -3851,7 +4395,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^4.2.4, @smithy/invalid-dependency@npm:^4.2.5": +"@smithy/invalid-dependency@npm:^4.2.4, @smithy/invalid-dependency@npm:^4.2.5, @smithy/invalid-dependency@npm:^4.2.6": version: 4.2.6 resolution: "@smithy/invalid-dependency@npm:4.2.6" dependencies: @@ -3879,7 +4423,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^4.2.4, @smithy/middleware-content-length@npm:^4.2.5": +"@smithy/middleware-content-length@npm:^4.2.4, @smithy/middleware-content-length@npm:^4.2.5, @smithy/middleware-content-length@npm:^4.2.6": version: 4.2.6 resolution: "@smithy/middleware-content-length@npm:4.2.6" dependencies: @@ -3906,7 +4450,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.4.14, @smithy/middleware-retry@npm:^4.4.6": +"@smithy/middleware-retry@npm:^4.4.14, @smithy/middleware-retry@npm:^4.4.16, @smithy/middleware-retry@npm:^4.4.6": version: 4.4.16 resolution: "@smithy/middleware-retry@npm:4.4.16" dependencies: @@ -4138,7 +4682,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.3.13, @smithy/util-defaults-mode-browser@npm:^4.3.5": +"@smithy/util-defaults-mode-browser@npm:^4.3.13, @smithy/util-defaults-mode-browser@npm:^4.3.15, @smithy/util-defaults-mode-browser@npm:^4.3.5": version: 4.3.15 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.15" dependencies: @@ -4150,7 +4694,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.2.16, @smithy/util-defaults-mode-node@npm:^4.2.8": +"@smithy/util-defaults-mode-node@npm:^4.2.16, @smithy/util-defaults-mode-node@npm:^4.2.18, @smithy/util-defaults-mode-node@npm:^4.2.8": version: 4.2.18 resolution: "@smithy/util-defaults-mode-node@npm:4.2.18" dependencies: @@ -5642,6 +6186,7 @@ __metadata: dependencies: "@amplitude/node": 1.10.2 "@ava/typescript": 6.0.0 + "@aws-sdk/client-bedrock-runtime": ^3.954.0 "@aws-sdk/lib-dynamodb": ^3.953.0 "@electric-sql/pglite": ^0.3.14 "@faker-js/faker": ^10.1.0 From aa2ca39c682fad1805f58558ea88e1c01a4b2b7e Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 22 Dec 2025 09:18:26 +0000 Subject: [PATCH 3/5] update modelId for AmazonBedrockAiProvider to latest version --- .../entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts b/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts index cbdf9bbc..d849309a 100644 --- a/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts +++ b/backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts @@ -5,7 +5,7 @@ import { IAIProvider } from './ai-provider.interface.js'; @Injectable() export class AmazonBedrockAiProvider implements IAIProvider { private readonly bedrockRuntimeClient: BedrockRuntimeClient; - private readonly modelId: string = 'global.anthropic.claude-sonnet-4-20250514-v1:0'; + private readonly modelId: string = 'global.anthropic.claude-sonnet-4-5-20250929-v1:0'; private readonly temperature: number = 0.7; private readonly maxTokens: number = 1024; private readonly region: string = 'us-west-2'; From 3d27a6efa7b90a539b49ebad4751326834c9bfaf Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 22 Dec 2025 10:15:16 +0000 Subject: [PATCH 4/5] update tests to expect zero table widgets for various user permissions scenarios --- .../non-saas-tests/non-saas-table-widgets-e2e.test.ts | 2 +- .../non-saas-user-admin-permissions-e2e.test.ts | 2 +- .../non-saas-user-group-edit-permissions-e2e.test.ts | 4 ++-- ...ifferent-group-connection-readonly-permissions-e2e.test.ts | 4 ++-- .../non-saas-user-with-table-only-permissions-e2e.test.ts | 2 +- backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts | 4 ++-- .../ava-tests/saas-tests/user-admin-permissions-e2e.test.ts | 4 ++-- .../saas-tests/user-group-edit-permissions-e2e.test.ts | 4 ++-- ...ifferent-group-connection-readonly-permissions-e2e.test.ts | 4 ++-- .../saas-tests/user-with-table-only-permissions-e2e.test.ts | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-widgets-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-widgets-e2e.test.ts index cff87731..c0abc091 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-widgets-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-widgets-e2e.test.ts @@ -86,7 +86,7 @@ test.serial(`${currentTest} should return empty array, table widgets not created const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); t.is(typeof getTableWidgetsRO, 'object'); - t.is(getTableWidgetsRO.length, 2); + t.is(getTableWidgetsRO.length, 0); }); test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-admin-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-admin-permissions-e2e.test.ts index 4cd5f1bf..5c88eb0c 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-admin-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-admin-permissions-e2e.test.ts @@ -1888,7 +1888,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (error) { console.error(error); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-group-edit-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-group-edit-permissions-e2e.test.ts index f689d6e0..4d3fc148 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-group-edit-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-group-edit-permissions-e2e.test.ts @@ -1689,7 +1689,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); @@ -2784,7 +2784,7 @@ test.serial(`${currentTest} should return empty widgets array when widgets not c const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); t.is(typeof getTableWidgetsRO, 'object'); - t.is(getTableWidgetsRO.length, 1); + t.is(getTableWidgetsRO.length, 0); } catch (e) { console.error(e); } diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts index eef5d2cb..7abcc52f 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts @@ -1622,7 +1622,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); @@ -2759,7 +2759,7 @@ test.serial(`${currentTest} should return empty widgets array when widgets not c .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); - t.is(getTableWidgetsRO.length, 1); + t.is(getTableWidgetsRO.length, 0); } catch (e) { console.error(e); throw e; diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts index 95a500ba..49d880fa 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts @@ -1556,7 +1556,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); diff --git a/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts index 20fa82b3..0ec02dfc 100644 --- a/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts @@ -94,10 +94,10 @@ test.serial(`${currentTest} should return empty array, table widgets not created const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); t.is(typeof getTableWidgetsRO, 'object'); - t.is(getTableWidgetsRO.length, 2); + t.is(getTableWidgetsRO.length, 0); }); -test.serial( +test.skip( `${currentTest} should return automatically created widgets array, if table contains specific data`, async (t) => { const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; diff --git a/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts index a58bac39..209d9c5f 100644 --- a/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts @@ -1888,7 +1888,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (error) { console.error(error); @@ -3553,7 +3553,7 @@ test.serial(`${currentTest} should return empty widgets array when widgets not c const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); t.is(typeof getTableWidgetsRO, 'object'); - t.is(getTableWidgetsRO.length, 1); + t.is(getTableWidgetsRO.length, 0); } catch (error) { console.error(error); throw error; diff --git a/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts index a04a8320..3056b5ee 100644 --- a/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts @@ -1709,7 +1709,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); @@ -2801,7 +2801,7 @@ test.serial(`${currentTest} should return empty widgets array when widgets not c const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); t.is(typeof getTableWidgetsRO, 'object'); - t.is(getTableWidgetsRO.length, 1); + t.is(getTableWidgetsRO.length, 0); } catch (e) { console.error(e); } diff --git a/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts index 5bd9b014..48a9c383 100644 --- a/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts @@ -1631,7 +1631,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); @@ -2812,7 +2812,7 @@ test.serial(`${currentTest} should return empty widgets array when widgets not c .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 200); - t.is(getTableWidgetsRO.length, 1); + t.is(getTableWidgetsRO.length, 0); } catch (e) { console.error(e); throw e; diff --git a/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts index 4fa64551..a25752a1 100644 --- a/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts @@ -1564,7 +1564,7 @@ test.serial(`${currentTest} should return table structure`, async (t) => { t.is(primaryColumns[0].column_name, 'id'); t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 1); + t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); } catch (e) { console.error(e); From 48ccf923600c1a053f4d8e523203e11ed66b695c Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 22 Dec 2025 11:09:45 +0000 Subject: [PATCH 5/5] add AI settings and widgets creation use case and controller endpoint --- backend/src/common/data-injection.tokens.ts | 1 + .../src/entities/ai/ai-use-cases.interface.ts | 5 +++ backend/src/entities/ai/ai.module.ts | 16 +++++++-- ...-settings-and-widgets-creation.use.case.ts | 33 +++++++++++++++++ .../ai/user-ai-requests-v2.controller.ts | 36 +++++++++++++++++-- 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts diff --git a/backend/src/common/data-injection.tokens.ts b/backend/src/common/data-injection.tokens.ts index bb0176b5..4fb4f395 100644 --- a/backend/src/common/data-injection.tokens.ts +++ b/backend/src/common/data-injection.tokens.ts @@ -154,6 +154,7 @@ export enum UseCaseType { DELETE_API_KEY = 'DELETE_API_KEY', REQUEST_INFO_FROM_TABLE_WITH_AI_V2 = 'REQUEST_INFO_FROM_TABLE_WITH_AI_V2', + REQUEST_AI_SETTINGS_AND_WIDGETS_CREATION = 'REQUEST_AI_SETTINGS_AND_WIDGETS_CREATION', CREATE_TABLE_FILTERS = 'CREATE_TABLE_FILTERS', FIND_TABLE_FILTERS = 'FIND_TABLE_FILTERS', diff --git a/backend/src/entities/ai/ai-use-cases.interface.ts b/backend/src/entities/ai/ai-use-cases.interface.ts index 2d5ac76f..5df99281 100644 --- a/backend/src/entities/ai/ai-use-cases.interface.ts +++ b/backend/src/entities/ai/ai-use-cases.interface.ts @@ -1,6 +1,11 @@ import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; +import { FindOneConnectionDs } from '../connection/application/data-structures/find-one-connection.ds.js'; import { RequestInfoFromTableDSV2 } from './application/data-structures/request-info-from-table.ds.js'; export interface IRequestInfoFromTableV2 { execute(inputData: RequestInfoFromTableDSV2, inTransaction: InTransactionEnum): Promise; } + +export interface IAISettingsAndWidgetsCreation { + execute(connectionData: FindOneConnectionDs, inTransaction: InTransactionEnum): Promise; +} diff --git a/backend/src/entities/ai/ai.module.ts b/backend/src/entities/ai/ai.module.ts index 49152c38..d3ffe295 100644 --- a/backend/src/entities/ai/ai.module.ts +++ b/backend/src/entities/ai/ai.module.ts @@ -5,10 +5,11 @@ import { GlobalDatabaseContext } from '../../common/application/global-database- import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { UserEntity } from '../user/user.entity.js'; -import { RequestInfoFromTableWithAIUseCaseV4 } from './use-cases/request-info-from-table-with-ai-v4.use.case.js'; -import { UserAIRequestsControllerV2 } from './user-ai-requests-v2.controller.js'; import { AiService } from './ai.service.js'; import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.provider.js'; +import { RequestInfoFromTableWithAIUseCaseV4 } from './use-cases/request-info-from-table-with-ai-v4.use.case.js'; +import { UserAIRequestsControllerV2 } from './user-ai-requests-v2.controller.js'; +import { RequestAISettingsAndWidgetsCreationUseCase } from './use-cases/request-ai-settings-and-widgets-creation.use.case.js'; @Global() @Module({ @@ -22,6 +23,10 @@ import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.prov provide: UseCaseType.REQUEST_INFO_FROM_TABLE_WITH_AI_V2, useClass: RequestInfoFromTableWithAIUseCaseV4, }, + { + provide: UseCaseType.REQUEST_AI_SETTINGS_AND_WIDGETS_CREATION, + useClass: RequestAISettingsAndWidgetsCreationUseCase, + }, AmazonBedrockAiProvider, AiService, ], @@ -30,6 +35,11 @@ import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.prov }) export class AIModule implements NestModule { public configure(consumer: MiddlewareConsumer): any { - consumer.apply(AuthMiddleware).forRoutes({ path: '/ai/v2/request/:connectionId', method: RequestMethod.POST }); + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/ai/v2/request/:connectionId', method: RequestMethod.POST }, + { path: '/ai/v2/setup/:connectionId', method: RequestMethod.GET }, + ); } } diff --git a/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts new file mode 100644 index 00000000..4c805520 --- /dev/null +++ b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts @@ -0,0 +1,33 @@ +import { BadRequestException, Inject, Injectable, Scope } from '@nestjs/common'; +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; +import { IAISettingsAndWidgetsCreation } from '../ai-use-cases.interface.js'; +import { SharedJobsService } from '../../shared-jobs/shared-jobs.service.js'; +import { FindOneConnectionDs } from '../../connection/application/data-structures/find-one-connection.ds.js'; +import { Messages } from '../../../exceptions/text/messages.js'; + +@Injectable({ scope: Scope.REQUEST }) +export class RequestAISettingsAndWidgetsCreationUseCase + extends AbstractUseCase + implements IAISettingsAndWidgetsCreation +{ + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly sharedJobsService: SharedJobsService, + ) { + super(); + } + + public async implementation(connectionData: FindOneConnectionDs): Promise { + const { connectionId, masterPwd } = connectionData; + + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + if (!connection) { + throw new BadRequestException(Messages.CONNECTION_NOT_FOUND); + } + + await this.sharedJobsService.scanDatabaseAndCreateSettingsAndWidgetsWithAI(connection); + } +} diff --git a/backend/src/entities/ai/user-ai-requests-v2.controller.ts b/backend/src/entities/ai/user-ai-requests-v2.controller.ts index b09a606e..92ce7cb2 100644 --- a/backend/src/entities/ai/user-ai-requests-v2.controller.ts +++ b/backend/src/entities/ai/user-ai-requests-v2.controller.ts @@ -1,4 +1,15 @@ -import { Body, Controller, Inject, Injectable, Post, Query, Res, UseGuards, UseInterceptors } from '@nestjs/common'; +import { + Body, + Controller, + Get, + Inject, + Injectable, + Post, + Query, + Res, + UseGuards, + UseInterceptors, +} from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { Response } from 'express'; import { UseCaseType } from '../../common/data-injection.tokens.js'; @@ -10,7 +21,7 @@ import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; import { TableReadGuard } from '../../guards/table-read.guard.js'; import { ValidationHelper } from '../../helpers/validators/validation-helper.js'; import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; -import { IRequestInfoFromTableV2 } from './ai-use-cases.interface.js'; +import { IAISettingsAndWidgetsCreation, IRequestInfoFromTableV2 } from './ai-use-cases.interface.js'; import { RequestInfoFromTableDSV2 } from './application/data-structures/request-info-from-table.ds.js'; import { RequestInfoFromTableBodyDTO } from './application/dto/request-info-from-table-body.dto.js'; @@ -23,6 +34,8 @@ export class UserAIRequestsControllerV2 { constructor( @Inject(UseCaseType.REQUEST_INFO_FROM_TABLE_WITH_AI_V2) private readonly requestInfoFromTableWithAIUseCase: IRequestInfoFromTableV2, + @Inject(UseCaseType.REQUEST_AI_SETTINGS_AND_WIDGETS_CREATION) + private readonly requestAISettingsAndWidgetsCreationUseCase: IAISettingsAndWidgetsCreation, ) {} @ApiOperation({ summary: 'Request info from table in connection with AI (Version 2)' }) @@ -61,4 +74,23 @@ export class UserAIRequestsControllerV2 { }; return await this.requestInfoFromTableWithAIUseCase.execute(inputData, InTransactionEnum.OFF); } + + @ApiOperation({ summary: 'Request AI settings and widgets creation for connection' }) + @ApiResponse({ + status: 200, + description: 'AI settings and widgets creation job has been queued.', + }) + @Get('/ai/v2/setup/:connectionId') + public async requestAISettingsAndWidgetsCreation( + @SlugUuid('connectionId') connectionId: string, + @MasterPassword() masterPassword: string, + @UserId() userId: string, + ): Promise { + const connectionData = { + connectionId, + masterPwd: masterPassword, + cognitoUserName: userId, + }; + return await this.requestAISettingsAndWidgetsCreationUseCase.execute(connectionData, InTransactionEnum.OFF); + } }