import { EndpointRegistry, HttpClient } from "./HttpClient"; import { ACCOUNT_HEADER, getAccountId } from "@/lib/accountStore"; export class AuthenticationRequiredError extends Error { constructor() { super("Authentication is required before calling the API."); this.name = "AuthenticationRequiredError"; } } export const apiEndpointKeys = { clouds: { list: "clouds.list", services: "clouds.services.list", status: "clouds.status.get", diagnostics: "clouds.diagnostics.get", serviceStatus: "clouds.services.status.get", schema: "clouds.services.schema.get", dependencies: "clouds.services.dependencies.get", resources: { list: "clouds.services.resources.list", get: "clouds.services.resources.get", create: "clouds.services.resources.create", update: "clouds.services.resources.update", delete: "clouds.services.resources.delete", invoke: "clouds.services.resources.invoke", start: "clouds.services.resources.start", stop: "clouds.services.resources.stop", reboot: "clouds.services.resources.reboot", deployLightsailStaticFiles: "clouds.services.resources.lightsail.static-files.deploy", deployLightsailNodeApplication: "clouds.services.resources.lightsail.node-application.deploy", publish: "clouds.services.resources.notifications.publish", createSnsSubscription: "clouds.services.resources.notifications.subscription.create", listSnsSubscriptions: "clouds.services.resources.notifications.subscriptions.list", deleteSnsSubscription: "clouds.services.resources.notifications.subscription.delete", encrypt: "clouds.services.resources.encrypt", decrypt: "clouds.services.resources.decrypt", createApiGatewayRoute: "clouds.services.resources.apigateway.route.create", listApiGatewayRoutes: "clouds.services.resources.apigateway.routes.list", deleteApiGatewayRoute: "clouds.services.resources.apigateway.route.delete", enableApiGatewayCors: "clouds.services.resources.apigateway.cors.enable", testApiGatewayRoute: "clouds.services.resources.apigateway.route.test", testApiGatewayMethod: "clouds.services.resources.apigateway.method.test", createS3LambdaTrigger: "clouds.services.resources.storage.lambda-trigger.create", listS3LambdaTriggers: "clouds.services.resources.storage.lambda-triggers.list", deleteS3LambdaTrigger: "clouds.services.resources.storage.lambda-trigger.delete", getS3BucketWebsite: "clouds.services.resources.storage.website.get", putS3BucketWebsite: "clouds.services.resources.storage.website.put", deleteS3BucketWebsite: "clouds.services.resources.storage.website.delete", createEventBridgeLambdaTrigger: "clouds.services.resources.serverless.eventbridge-trigger.create", listEventBridgeLambdaTriggers: "clouds.services.resources.serverless.eventbridge-triggers.list", deleteEventBridgeLambdaTrigger: "clouds.services.resources.serverless.eventbridge-trigger.delete", createEventBridgeRule: "clouds.services.resources.events.rule.create", listEventBridgeRules: "clouds.services.resources.events.rules.list", deleteEventBridgeRule: "clouds.services.resources.events.rule.delete", putEventBridgeEvent: "clouds.services.resources.events.event.put", listCloudFormationChangeSets: "clouds.services.resources.iac.change-sets.list", createCloudFormationChangeSet: "clouds.services.resources.iac.change-set.create", executeCloudFormationChangeSet: "clouds.services.resources.iac.change-set.execute", deleteCloudFormationChangeSet: "clouds.services.resources.iac.change-set.delete", updateCloudFormationTerminationProtection: "clouds.services.resources.iac.termination-protection.update", createSqsLambdaEventSourceMapping: "clouds.services.resources.serverless.sqs-event-source-mapping.create", listSqsLambdaEventSourceMappings: "clouds.services.resources.serverless.sqs-event-source-mappings.list", deleteSqsLambdaEventSourceMapping: "clouds.services.resources.serverless.sqs-event-source-mapping.delete", putKinesisRecord: "clouds.services.resources.kinesis.record.put", listKinesisRecords: "clouds.services.resources.kinesis.records.list", createLambdaEventSourceMapping: "clouds.services.resources.serverless.event-source-mapping.create", listLambdaEventSourceMappings: "clouds.services.resources.serverless.event-source-mappings.list", updateLambdaEventSourceMapping: "clouds.services.resources.serverless.event-source-mapping.update", deleteLambdaEventSourceMapping: "clouds.services.resources.serverless.event-source-mapping.delete", startWorkflowExecution: "clouds.services.resources.workflows.execution.start", listWorkflowExecutions: "clouds.services.resources.workflows.executions.list", describeWorkflowExecution: "clouds.services.resources.workflows.execution.describe", getWorkflowExecutionHistory: "clouds.services.resources.workflows.execution.history.get", stopWorkflowExecution: "clouds.services.resources.workflows.execution.stop", startCodeBuild: "clouds.services.resources.codebuild.build.start", listCodeBuilds: "clouds.services.resources.codebuild.builds.list", getCodeBuild: "clouds.services.resources.codebuild.build.get", startCodePipeline: "clouds.services.resources.codepipeline.execution.start", listCodePipelineExecutions: "clouds.services.resources.codepipeline.executions.list", getCodePipelineState: "clouds.services.resources.codepipeline.state.get", startCodeDeployDeployment: "clouds.services.resources.codedeploy.deployment.start", listCodeDeployDeployments: "clouds.services.resources.codedeploy.deployments.list", getCodeDeployDeployment: "clouds.services.resources.codedeploy.deployment.get", stopCodeDeployDeployment: "clouds.services.resources.codedeploy.deployment.stop", }, storage: { objects: { list: "clouds.services.storage.objects.list", upload: "clouds.services.storage.objects.upload", download: "clouds.services.storage.objects.download", delete: "clouds.services.storage.objects.delete", copy: "clouds.services.storage.objects.copy", }, }, nosql: { cosmos: { containers: { list: "clouds.services.nosql.cosmos.containers.list", create: "clouds.services.nosql.cosmos.containers.create", delete: "clouds.services.nosql.cosmos.containers.delete", }, items: { list: "clouds.services.nosql.cosmos.items.list", upsert: "clouds.services.nosql.cosmos.items.upsert", delete: "clouds.services.nosql.cosmos.items.delete", query: "clouds.services.nosql.cosmos.items.query", }, }, }, database: { sql: { databases: "clouds.services.database.sql.databases.list", tables: "clouds.services.database.sql.tables.list", query: "clouds.services.database.sql.query", }, snapshots: { list: "clouds.services.database.snapshots.list", create: "clouds.services.database.snapshots.create", }, orderableClasses: { list: "clouds.services.database.orderable-classes.list", }, }, logs: { query: "clouds.services.logs.query", filter: "clouds.services.logs.filter", }, messaging: { messages: {send: "clouds.services.messaging.messages.send", receive: "clouds.services.messaging.messages.receive", delete: "clouds.services.messaging.messages.delete", purge: "clouds.services.messaging.messages.purge"}, moveTasks: "clouds.services.messaging.move-tasks", }, monitoring: { metrics: "clouds.services.monitoring.metrics", metricData: "clouds.services.monitoring.metric-data", history: "clouds.services.monitoring.history", state: "clouds.services.monitoring.state", actions: "clouds.services.monitoring.actions", }, cdn: { enabled: "clouds.services.cdn.enabled", invalidations: "clouds.services.cdn.invalidations", }, userpools: { userAction: "clouds.services.userpools.users.action", userGroups: "clouds.services.userpools.users.groups", groups: { list: "clouds.services.userpools.groups.list", create: "clouds.services.userpools.groups.create", delete: "clouds.services.userpools.groups.delete", }, signInTest: "clouds.services.userpools.sign-in-test", client: { get: "clouds.services.userpools.clients.get", updateOAuth: "clouds.services.userpools.clients.update-oauth", }, }, k8s: { nodegroups: { list: "clouds.services.k8s.nodegroups.list", create: "clouds.services.k8s.nodegroups.create", delete: "clouds.services.k8s.nodegroups.delete", }, fargateProfiles: { list: "clouds.services.k8s.fargate-profiles.list", create: "clouds.services.k8s.fargate-profiles.create", delete: "clouds.services.k8s.fargate-profiles.delete", }, }, email: { inbox: { clear: "clouds.services.email.inbox.clear", }, }, childCollections: { list: "clouds.services.childCollections.list", items: { list: "clouds.services.childCollections.items.list", }, }, flatItems: { get: "clouds.services.flatItems.get", list: "clouds.services.flatItems.list", query: "clouds.services.flatItems.query", create: "clouds.services.flatItems.create", delete: "clouds.services.flatItems.delete", }, configuration: { environments: { list: "clouds.services.configuration.environments.list", create: "clouds.services.configuration.environments.create", delete: "clouds.services.configuration.environments.delete", deployments: { start: "clouds.services.configuration.environments.deployments.start", get: "clouds.services.configuration.environments.deployments.get", }, }, configurationProfiles: { list: "clouds.services.configuration.profiles.list", create: "clouds.services.configuration.profiles.create", delete: "clouds.services.configuration.profiles.delete", hostedVersions: { list: "clouds.services.configuration.profiles.hosted-versions.list", get: "clouds.services.configuration.profiles.hosted-versions.get", create: "clouds.services.configuration.profiles.hosted-versions.create", delete: "clouds.services.configuration.profiles.hosted-versions.delete", }, }, deploymentStrategies: { list: "clouds.services.configuration.deployment-strategies.list", create: "clouds.services.configuration.deployment-strategies.create", delete: "clouds.services.configuration.deployment-strategies.delete", }, }, }, aws: { eks: { clusters: { list: "aws.eks.clusters.list", describe: "aws.eks.clusters.describe", }, nodegroups: { list: "aws.eks.nodegroups.list", describe: "aws.eks.nodegroups.describe", create: "aws.eks.nodegroups.create", delete: "aws.eks.nodegroups.delete", }, fargateProfiles: { list: "aws.eks.fargate-profiles.list", describe: "aws.eks.fargate-profiles.describe", create: "aws.eks.fargate-profiles.create", delete: "aws.eks.fargate-profiles.delete", }, }, secretsmanager: { secrets: { list: "aws.secretsmanager.secrets.list", create: "aws.secretsmanager.secrets.create", describe: "aws.secretsmanager.secrets.describe", delete: "aws.secretsmanager.secrets.delete", value: { get: "aws.secretsmanager.secrets.value.get", put: "aws.secretsmanager.secrets.value.put", }, }, }, ec2: { instances: { list: "aws.ec2.instances.list", describe: "aws.ec2.instances.describe", create: "aws.ec2.instances.create", start: "aws.ec2.instances.start", stop: "aws.ec2.instances.stop", reboot: "aws.ec2.instances.reboot", terminate: "aws.ec2.instances.terminate", tags: "aws.ec2.instances.tags", securityGroups: "aws.ec2.instances.securityGroups", createImage: "aws.ec2.instances.create-image", console: "aws.ec2.instances.console", checkSsh: "aws.ec2.instances.ssh.check", }, amis: { list: "aws.ec2.amis.list", deregister: "aws.ec2.amis.deregister", }, keyPairs: { list: "aws.ec2.key-pairs.list", create: "aws.ec2.key-pairs.create", delete: "aws.ec2.key-pairs.delete", }, securityGroups: { list: "aws.ec2.security-groups.list", create: "aws.ec2.security-groups.create", delete: "aws.ec2.security-groups.delete", authorize: "aws.ec2.security-groups.authorize", revoke: "aws.ec2.security-groups.revoke", authorizeEgress: "aws.ec2.security-groups.authorize-egress", revokeEgress: "aws.ec2.security-groups.revoke-egress", }, vpcs: { list: "aws.ec2.vpcs.list", create: "aws.ec2.vpcs.create", delete: "aws.ec2.vpcs.delete", getAttributes: "aws.ec2.vpcs.get-attributes", modifyAttribute: "aws.ec2.vpcs.modify-attribute", }, subnets: { list: "aws.ec2.subnets.list", create: "aws.ec2.subnets.create", delete: "aws.ec2.subnets.delete", modifyAttribute: "aws.ec2.subnets.modify-attribute", }, internetGateways: { list: "aws.ec2.igw.list", create: "aws.ec2.igw.create", attach: "aws.ec2.igw.attach", detach: "aws.ec2.igw.detach", delete: "aws.ec2.igw.delete", }, natGateways: { list: "aws.ec2.nat.list", create: "aws.ec2.nat.create", delete: "aws.ec2.nat.delete", }, routeTables: { list: "aws.ec2.rtb.list", create: "aws.ec2.rtb.create", delete: "aws.ec2.rtb.delete", createRoute: "aws.ec2.rtb.route.create", deleteRoute: "aws.ec2.rtb.route.delete", associate: "aws.ec2.rtb.associate", disassociate: "aws.ec2.rtb.disassociate", }, elasticIps: { list: "aws.ec2.eip.list", create: "aws.ec2.eip.create", release: "aws.ec2.eip.release", associate: "aws.ec2.eip.associate", disassociate: "aws.ec2.eip.disassociate", }, availabilityZones: "aws.ec2.availability-zones", instanceTypes: "aws.ec2.instance-types", vpcWizard: "aws.ec2.vpc-wizard", }, }, } as const; export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "/api"; export const endpointRegistry: EndpointRegistry = new Map([ // Cloud Proxy [ apiEndpointKeys.clouds.list, { path: "/clouds", method: "GET", }, ], [ apiEndpointKeys.clouds.services, { path: "/clouds/:cloud/services", method: "GET", }, ], [ apiEndpointKeys.clouds.status, { path: "/clouds/:cloud/status", method: "GET", }, ], [ apiEndpointKeys.clouds.diagnostics, { path: "/clouds/:cloud/diagnostics", method: "GET", }, ], [ apiEndpointKeys.clouds.serviceStatus, { path: "/clouds/:cloud/services/:service/status", method: "GET", }, ], [ apiEndpointKeys.clouds.schema, { path: "/clouds/:cloud/services/:service/schema", method: "GET", }, ], [ apiEndpointKeys.clouds.dependencies, { path: "/clouds/:cloud/services/:service/dependencies", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.list, { path: "/clouds/:cloud/services/:service/resources", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.invoke, { path: "/clouds/:cloud/services/:service/resources/:id/invoke", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.createApiGatewayRoute, { path: "/clouds/:cloud/services/apigateway/resources/:id/routes", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.start, { path: "/clouds/:cloud/services/:service/resources/:id/start", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.stop, { path: "/clouds/:cloud/services/:service/resources/:id/stop", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.reboot, { path: "/clouds/:cloud/services/:service/resources/:id/reboot", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.publish, { path: "/clouds/:cloud/services/notifications/resources/:id/publish", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.createSnsSubscription, { path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.listSnsSubscriptions, { path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteSnsSubscription, { path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions/:subscriptionArn", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.listApiGatewayRoutes, { path: "/clouds/:cloud/services/apigateway/resources/:id/routes", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteApiGatewayRoute, { path: "/clouds/:cloud/services/apigateway/resources/:id/routes/:resourceId/:method", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.testApiGatewayRoute, { path: "/clouds/:cloud/services/apigateway/resources/:id/routes/test", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.testApiGatewayMethod, { path: "/clouds/:cloud/services/apigateway/resources/:id/methods/test", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.enableApiGatewayCors, { path: "/clouds/:cloud/services/apigateway/resources/:id/cors", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.createS3LambdaTrigger, { path: "/clouds/:cloud/services/storage/resources/:id/lambda-triggers", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.listS3LambdaTriggers, { path: "/clouds/:cloud/services/storage/resources/:id/lambda-triggers", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteS3LambdaTrigger, { path: "/clouds/:cloud/services/storage/resources/:id/lambda-triggers/:triggerId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.getS3BucketWebsite, { path: "/clouds/:cloud/services/storage/resources/:id/website", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.putS3BucketWebsite, { path: "/clouds/:cloud/services/storage/resources/:id/website", method: "PUT", }, ], [ apiEndpointKeys.clouds.resources.deleteS3BucketWebsite, { path: "/clouds/:cloud/services/storage/resources/:id/website", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.createEventBridgeLambdaTrigger, { path: "/clouds/:cloud/services/serverless/resources/:id/eventbridge-triggers", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.listEventBridgeLambdaTriggers, { path: "/clouds/:cloud/services/serverless/resources/:id/eventbridge-triggers", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteEventBridgeLambdaTrigger, { path: "/clouds/:cloud/services/serverless/resources/:id/eventbridge-triggers/:triggerId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.createEventBridgeRule, { path: "/clouds/:cloud/services/events/resources/:id/rules", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.listEventBridgeRules, { path: "/clouds/:cloud/services/events/resources/:id/rules", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteEventBridgeRule, { path: "/clouds/:cloud/services/events/resources/:id/rules/:ruleName", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.putEventBridgeEvent, { path: "/clouds/:cloud/services/events/resources/:id/events", method: "POST", }, ], [apiEndpointKeys.clouds.resources.listCloudFormationChangeSets, {path: "/clouds/:cloud/services/iac/resources/:id/change-sets", method: "GET"}], [apiEndpointKeys.clouds.resources.createCloudFormationChangeSet, {path: "/clouds/:cloud/services/iac/resources/:id/change-sets", method: "POST"}], [apiEndpointKeys.clouds.resources.executeCloudFormationChangeSet, {path: "/clouds/:cloud/services/iac/resources/:id/change-sets/:name/execute", method: "POST"}], [apiEndpointKeys.clouds.resources.deleteCloudFormationChangeSet, {path: "/clouds/:cloud/services/iac/resources/:id/change-sets/:name", method: "DELETE"}], [apiEndpointKeys.clouds.resources.updateCloudFormationTerminationProtection, {path: "/clouds/:cloud/services/iac/resources/:id/termination-protection", method: "PUT"}], [ apiEndpointKeys.clouds.resources.createSqsLambdaEventSourceMapping, { path: "/clouds/:cloud/services/serverless/resources/:id/sqs-event-source-mappings", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.listSqsLambdaEventSourceMappings, { path: "/clouds/:cloud/services/serverless/resources/:id/sqs-event-source-mappings", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.deleteSqsLambdaEventSourceMapping, { path: "/clouds/:cloud/services/serverless/resources/:id/sqs-event-source-mappings/:mappingId", method: "DELETE", }, ], [apiEndpointKeys.clouds.resources.putKinesisRecord, {path: "/clouds/:cloud/services/kinesis/resources/:id/records", method: "POST"}], [apiEndpointKeys.clouds.resources.listKinesisRecords, {path: "/clouds/:cloud/services/kinesis/resources/:id/records", method: "GET"}], [apiEndpointKeys.clouds.resources.createLambdaEventSourceMapping, {path: "/clouds/:cloud/services/serverless/event-source-mappings", method: "POST"}], [apiEndpointKeys.clouds.resources.listLambdaEventSourceMappings, {path: "/clouds/:cloud/services/serverless/event-source-mappings", method: "GET"}], [apiEndpointKeys.clouds.resources.updateLambdaEventSourceMapping, {path: "/clouds/:cloud/services/serverless/event-source-mappings/:mappingId", method: "PATCH"}], [apiEndpointKeys.clouds.resources.deleteLambdaEventSourceMapping, {path: "/clouds/:cloud/services/serverless/event-source-mappings/:mappingId", method: "DELETE"}], [ apiEndpointKeys.clouds.resources.startWorkflowExecution, { path: "/clouds/:cloud/services/workflows/resources/:id/executions", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.listWorkflowExecutions, { path: "/clouds/:cloud/services/workflows/resources/:id/executions", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.describeWorkflowExecution, { path: "/clouds/:cloud/services/workflows/resources/:id/executions/:executionArn", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.getWorkflowExecutionHistory, { path: "/clouds/:cloud/services/workflows/resources/:id/executions/:executionArn/history", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.stopWorkflowExecution, { path: "/clouds/:cloud/services/workflows/resources/:id/executions/:executionArn/stop", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.startCodeBuild, { path: "/clouds/:cloud/services/codebuild/resources/:id/builds", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.listCodeBuilds, { path: "/clouds/:cloud/services/codebuild/resources/:id/builds", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.getCodeBuild, { path: "/clouds/:cloud/services/codebuild/resources/:id/builds/:buildId", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.startCodePipeline, { path: "/clouds/:cloud/services/codepipeline/resources/:id/executions", method: "POST" }, ], [ apiEndpointKeys.clouds.resources.listCodePipelineExecutions, { path: "/clouds/:cloud/services/codepipeline/resources/:id/executions", method: "GET" }, ], [ apiEndpointKeys.clouds.resources.getCodePipelineState, { path: "/clouds/:cloud/services/codepipeline/resources/:id/state", method: "GET" }, ], [apiEndpointKeys.clouds.resources.startCodeDeployDeployment, {path: "/clouds/:cloud/services/codedeploy/resources/:id/deployments", method: "POST"}], [apiEndpointKeys.clouds.resources.listCodeDeployDeployments, {path: "/clouds/:cloud/services/codedeploy/resources/:id/deployments", method: "GET"}], [apiEndpointKeys.clouds.resources.getCodeDeployDeployment, {path: "/clouds/:cloud/services/codedeploy/deployments/:deploymentId", method: "GET"}], [apiEndpointKeys.clouds.resources.stopCodeDeployDeployment, {path: "/clouds/:cloud/services/codedeploy/deployments/:deploymentId/stop", method: "POST"}], [ apiEndpointKeys.clouds.resources.get, { path: "/clouds/:cloud/services/:service/resources/:id", method: "GET", }, ], [ apiEndpointKeys.clouds.resources.encrypt, { path: "/clouds/:cloud/services/kms/resources/:id/encrypt", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.decrypt, { path: "/clouds/:cloud/services/kms/resources/:id/decrypt", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.create, { path: "/clouds/:cloud/services/:service/resources", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.update, { path: "/clouds/:cloud/services/:service/resources/:id", method: "PATCH", }, ], [ apiEndpointKeys.clouds.resources.deployLightsailStaticFiles, { path: "/clouds/aws/services/lightsail/resources/:id/static-files", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.deployLightsailNodeApplication, { path: "/clouds/aws/services/lightsail/resources/:id/node-application", method: "POST", }, ], [ apiEndpointKeys.clouds.resources.delete, { path: "/clouds/:cloud/services/:service/resources/:id", method: "DELETE", }, ], [ apiEndpointKeys.clouds.resources.invoke, { path: "/clouds/:cloud/services/:service/resources/:id/invoke", method: "POST", }, ], [ apiEndpointKeys.clouds.storage.objects.list, { path: "/clouds/:cloud/services/storage/resources/:id/objects", method: "GET", }, ], [ apiEndpointKeys.clouds.storage.objects.upload, { path: "/clouds/:cloud/services/storage/resources/:id/object", method: "PUT", }, ], [ apiEndpointKeys.clouds.storage.objects.download, { path: "/clouds/:cloud/services/storage/resources/:id/object", method: "GET", }, ], [ apiEndpointKeys.clouds.storage.objects.delete, { path: "/clouds/:cloud/services/storage/resources/:id/object", method: "DELETE", }, ], [ apiEndpointKeys.clouds.storage.objects.copy, { path: "/clouds/:cloud/services/storage/resources/:id/object/copy", method: "POST", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.containers.list, { path: "/clouds/:cloud/services/nosql/resources/:id/containers", method: "GET", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.containers.create, { path: "/clouds/:cloud/services/nosql/resources/:id/containers", method: "POST", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.containers.delete, { path: "/clouds/:cloud/services/nosql/resources/:id/containers/:containerId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.items.list, { path: "/clouds/:cloud/services/nosql/resources/:id/containers/:containerId/items", method: "GET", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.items.upsert, { path: "/clouds/:cloud/services/nosql/resources/:id/containers/:containerId/items", method: "POST", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.items.delete, { path: "/clouds/:cloud/services/nosql/resources/:id/containers/:containerId/items/:itemId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.nosql.cosmos.items.query, { path: "/clouds/:cloud/services/nosql/resources/:id/containers/:containerId/query", method: "POST", }, ], [ apiEndpointKeys.clouds.database.sql.databases, { path: "/clouds/:cloud/services/database/resources/:id/sql/databases", method: "POST", }, ], [ apiEndpointKeys.clouds.database.sql.tables, { path: "/clouds/:cloud/services/database/resources/:id/sql/tables", method: "POST", }, ], [ apiEndpointKeys.clouds.database.sql.query, { path: "/clouds/:cloud/services/database/resources/:id/sql/query", method: "POST", }, ], [ apiEndpointKeys.clouds.logs.query, { path: "/clouds/:cloud/services/logs/resources/:id/query", method: "POST", }, ], [ apiEndpointKeys.clouds.logs.filter, { path: "/clouds/:cloud/services/logs/resources/:id/filter", method: "POST", }, ], [apiEndpointKeys.clouds.messaging.messages.send, {path: "/clouds/:cloud/services/messaging/resources/:id/messages", method: "POST"}], [apiEndpointKeys.clouds.messaging.messages.receive, {path: "/clouds/:cloud/services/messaging/resources/:id/messages/receive", method: "POST"}], [apiEndpointKeys.clouds.messaging.messages.delete, {path: "/clouds/:cloud/services/messaging/resources/:id/messages/delete", method: "POST"}], [apiEndpointKeys.clouds.messaging.messages.purge, {path: "/clouds/:cloud/services/messaging/resources/:id/messages", method: "DELETE"}], [apiEndpointKeys.clouds.messaging.moveTasks, {path: "/clouds/:cloud/services/messaging/resources/:id/move-tasks", method: "POST"}], [ apiEndpointKeys.clouds.database.snapshots.list, { path: "/clouds/:cloud/services/database/snapshots", method: "GET", }, ], [ apiEndpointKeys.clouds.database.snapshots.create, { path: "/clouds/:cloud/services/database/snapshots", method: "POST", }, ], [ apiEndpointKeys.clouds.database.orderableClasses.list, { path: "/clouds/:cloud/services/database/orderable-classes", method: "GET", }, ], [ apiEndpointKeys.clouds.userpools.userAction, { path: "/clouds/:cloud/services/userpools/resources/:id/users/:username/actions", method: "POST", }, ], [ apiEndpointKeys.clouds.userpools.userGroups, { path: "/clouds/:cloud/services/userpools/resources/:id/users/:username/groups", method: "PUT", }, ], [ apiEndpointKeys.clouds.userpools.groups.list, { path: "/clouds/:cloud/services/userpools/resources/:id/groups", method: "GET", }, ], [ apiEndpointKeys.clouds.userpools.groups.create, { path: "/clouds/:cloud/services/userpools/resources/:id/groups", method: "POST", }, ], [ apiEndpointKeys.clouds.userpools.groups.delete, { path: "/clouds/:cloud/services/userpools/resources/:id/groups/:groupName", method: "DELETE", }, ], [ apiEndpointKeys.clouds.userpools.signInTest, { path: "/clouds/:cloud/services/userpools/resources/:id/sign-in-test", method: "POST", }, ], [apiEndpointKeys.clouds.monitoring.metrics, {path: "/clouds/:cloud/services/monitoring/metrics", method: "GET"}], [apiEndpointKeys.clouds.monitoring.metricData, {path: "/clouds/:cloud/services/monitoring/metric-data", method: "POST"}], [apiEndpointKeys.clouds.monitoring.history, {path: "/clouds/:cloud/services/monitoring/resources/:id/history", method: "GET"}], [apiEndpointKeys.clouds.monitoring.state, {path: "/clouds/:cloud/services/monitoring/resources/:id/state", method: "PUT"}], [apiEndpointKeys.clouds.monitoring.actions, {path: "/clouds/:cloud/services/monitoring/resources/:id/actions", method: "PUT"}], [ apiEndpointKeys.clouds.cdn.enabled, { path: "/clouds/:cloud/services/cdn/resources/:id/enabled", method: "PUT", }, ], [ apiEndpointKeys.clouds.cdn.invalidations, { path: "/clouds/:cloud/services/cdn/resources/:id/invalidations", method: "POST", }, ], [ apiEndpointKeys.clouds.userpools.client.get, { path: "/clouds/:cloud/services/userpools/resources/:id/clients/:clientId", method: "GET", }, ], [ apiEndpointKeys.clouds.userpools.client.updateOAuth, { path: "/clouds/:cloud/services/userpools/resources/:id/clients/:clientId/oauth", method: "PUT", }, ], [ apiEndpointKeys.clouds.k8s.nodegroups.list, { path: "/clouds/:cloud/services/k8s/resources/:id/nodegroups", method: "GET", }, ], [ apiEndpointKeys.clouds.k8s.nodegroups.create, { path: "/clouds/:cloud/services/k8s/resources/:id/nodegroups", method: "POST", }, ], [ apiEndpointKeys.clouds.k8s.nodegroups.delete, { path: "/clouds/:cloud/services/k8s/resources/:id/nodegroups/:nodegroupId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.k8s.fargateProfiles.list, { path: "/clouds/:cloud/services/k8s/resources/:id/fargate-profiles", method: "GET", }, ], [ apiEndpointKeys.clouds.k8s.fargateProfiles.create, { path: "/clouds/:cloud/services/k8s/resources/:id/fargate-profiles", method: "POST", }, ], [ apiEndpointKeys.clouds.k8s.fargateProfiles.delete, { path: "/clouds/:cloud/services/k8s/resources/:id/fargate-profiles/:profileId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.email.inbox.clear, { path: "/clouds/:cloud/services/email/inbox", method: "DELETE", }, ], [ apiEndpointKeys.clouds.configuration.environments.list, { path: "/clouds/:cloud/services/configuration/resources/:id/environments", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.environments.create, { path: "/clouds/:cloud/services/configuration/resources/:id/environments", method: "POST", }, ], [ apiEndpointKeys.clouds.configuration.environments.delete, { path: "/clouds/:cloud/services/configuration/resources/:id/environments/:environmentId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.configuration.environments.deployments.start, { path: "/clouds/:cloud/services/configuration/resources/:id/environments/:environmentId/deployments", method: "POST", }, ], [ apiEndpointKeys.clouds.configuration.environments.deployments.get, { path: "/clouds/:cloud/services/configuration/resources/:id/environments/:environmentId/deployments/:deploymentNumber", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.list, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.create, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles", method: "POST", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.delete, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles/:profileId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.hostedVersions.list, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles/:profileId/hosted-configuration-versions", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.hostedVersions.get, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles/:profileId/hosted-configuration-versions/:versionNumber", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.hostedVersions.create, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles/:profileId/hosted-configuration-versions", method: "POST", }, ], [ apiEndpointKeys.clouds.configuration.configurationProfiles.hostedVersions.delete, { path: "/clouds/:cloud/services/configuration/resources/:id/configuration-profiles/:profileId/hosted-configuration-versions/:versionNumber", method: "DELETE", }, ], [ apiEndpointKeys.clouds.configuration.deploymentStrategies.list, { path: "/clouds/:cloud/services/configuration/deployment-strategies", method: "GET", }, ], [ apiEndpointKeys.clouds.configuration.deploymentStrategies.create, { path: "/clouds/:cloud/services/configuration/deployment-strategies", method: "POST", }, ], [ apiEndpointKeys.clouds.configuration.deploymentStrategies.delete, { path: "/clouds/:cloud/services/configuration/deployment-strategies/:strategyId", method: "DELETE", }, ], [ apiEndpointKeys.clouds.childCollections.list, { path: "/clouds/:cloud/services/:service/resources/:id/collections", method: "GET", }, ], [ apiEndpointKeys.clouds.childCollections.items.list, { path: "/clouds/:cloud/services/:service/resources/:id/collections/:cid/items", method: "GET", }, ], [ apiEndpointKeys.clouds.flatItems.get, { path: "/clouds/:cloud/services/:service/resources/:id/items/:itemId", method: "GET", }, ], [ apiEndpointKeys.clouds.flatItems.list, { path: "/clouds/:cloud/services/:service/resources/:id/items", method: "GET", }, ], [ apiEndpointKeys.clouds.flatItems.query, { path: "/clouds/:cloud/services/:service/resources/:id/query", method: "POST", }, ], [ apiEndpointKeys.clouds.flatItems.create, { path: "/clouds/:cloud/services/:service/resources/:id/items", method: "POST", }, ], [ apiEndpointKeys.clouds.flatItems.delete, { path: "/clouds/:cloud/services/:service/resources/:id/items/:itemId", method: "DELETE", }, ], // AWS EKS [ apiEndpointKeys.aws.eks.clusters.list, { path: "/eks/clusters", method: "GET", }, ], [ apiEndpointKeys.aws.eks.clusters.describe, { path: "/eks/clusters/:name", method: "GET", }, ], [ apiEndpointKeys.aws.eks.nodegroups.list, { path: "/eks/clusters/:name/nodegroups", method: "GET", }, ], [ apiEndpointKeys.aws.eks.nodegroups.describe, { path: "/eks/clusters/:name/nodegroups/:nodegroup", method: "GET", }, ], [ apiEndpointKeys.aws.eks.nodegroups.create, { path: "/eks/clusters/:name/nodegroups", method: "POST", }, ], [ apiEndpointKeys.aws.eks.nodegroups.delete, { path: "/eks/clusters/:name/nodegroups/:nodegroup", method: "DELETE", }, ], [ apiEndpointKeys.aws.eks.fargateProfiles.list, { path: "/eks/clusters/:name/fargate-profiles", method: "GET", }, ], [ apiEndpointKeys.aws.eks.fargateProfiles.describe, { path: "/eks/clusters/:name/fargate-profiles/:profile", method: "GET", }, ], [ apiEndpointKeys.aws.eks.fargateProfiles.create, { path: "/eks/clusters/:name/fargate-profiles", method: "POST", }, ], [ apiEndpointKeys.aws.eks.fargateProfiles.delete, { path: "/eks/clusters/:name/fargate-profiles/:profile", method: "DELETE", }, ], // AWS Secrets Manager [ apiEndpointKeys.aws.secretsmanager.secrets.list, { path: "/secretsmanager/secrets", method: "GET", }, ], [ apiEndpointKeys.aws.secretsmanager.secrets.create, { path: "/secretsmanager/secrets", method: "POST", }, ], [ apiEndpointKeys.aws.secretsmanager.secrets.describe, { path: "/secretsmanager/secret", method: "GET", }, ], [ apiEndpointKeys.aws.secretsmanager.secrets.delete, { path: "/secretsmanager/secret", method: "DELETE", }, ], [ apiEndpointKeys.aws.secretsmanager.secrets.value.get, { path: "/secretsmanager/secret/value", method: "GET", }, ], [ apiEndpointKeys.aws.secretsmanager.secrets.value.put, { path: "/secretsmanager/secret/value", method: "PUT", }, ], // AWS EC2 [apiEndpointKeys.aws.ec2.instances.list, { path: "/ec2/instances", method: "GET" }], [apiEndpointKeys.aws.ec2.instances.describe, { path: "/ec2/instances/:instanceId", method: "GET" }], [apiEndpointKeys.aws.ec2.instances.create, { path: "/ec2/instances", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.start, { path: "/ec2/instances/:instanceId/start", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.stop, { path: "/ec2/instances/:instanceId/stop", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.reboot, { path: "/ec2/instances/:instanceId/reboot", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.terminate,{ path: "/ec2/instances/:instanceId/terminate", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.tags, { path: "/ec2/instances/:instanceId/tags", method: "PUT" }], [apiEndpointKeys.aws.ec2.instances.securityGroups, { path: "/ec2/instances/:instanceId/security-groups", method: "PUT" }], [apiEndpointKeys.aws.ec2.instances.createImage, { path: "/ec2/instances/:instanceId/image", method: "POST" }], [apiEndpointKeys.aws.ec2.instances.console, { path: "/ec2/instances/:instanceId/console", method: "GET" }], [apiEndpointKeys.aws.ec2.instances.checkSsh, { path: "/ec2/instances/:instanceId/ssh/check", method: "POST" }], [apiEndpointKeys.aws.ec2.amis.list, { path: "/ec2/amis", method: "GET" }], [apiEndpointKeys.aws.ec2.amis.deregister, { path: "/ec2/amis/:imageId/deregister", method: "POST" }], [apiEndpointKeys.aws.ec2.keyPairs.list, { path: "/ec2/key-pairs", method: "GET" }], [apiEndpointKeys.aws.ec2.keyPairs.create, { path: "/ec2/key-pairs", method: "POST" }], [apiEndpointKeys.aws.ec2.keyPairs.delete, { path: "/ec2/key-pairs/:name", method: "DELETE" }], [apiEndpointKeys.aws.ec2.securityGroups.list, { path: "/ec2/security-groups", method: "GET" }], [apiEndpointKeys.aws.ec2.securityGroups.create, { path: "/ec2/security-groups", method: "POST" }], [apiEndpointKeys.aws.ec2.securityGroups.delete, { path: "/ec2/security-groups/:groupId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.securityGroups.authorize, { path: "/ec2/security-groups/:groupId/ingress", method: "POST" }], [apiEndpointKeys.aws.ec2.securityGroups.revoke, { path: "/ec2/security-groups/:groupId/ingress", method: "DELETE" }], [apiEndpointKeys.aws.ec2.securityGroups.authorizeEgress, { path: "/ec2/security-groups/:groupId/egress", method: "POST" }], [apiEndpointKeys.aws.ec2.securityGroups.revokeEgress, { path: "/ec2/security-groups/:groupId/egress", method: "DELETE" }], [apiEndpointKeys.aws.ec2.vpcs.list, { path: "/ec2/vpcs", method: "GET" }], [apiEndpointKeys.aws.ec2.vpcs.create, { path: "/ec2/vpcs", method: "POST" }], [apiEndpointKeys.aws.ec2.vpcs.delete, { path: "/ec2/vpcs/:vpcId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.vpcs.getAttributes, { path: "/ec2/vpcs/:vpcId/attributes", method: "GET" }], [apiEndpointKeys.aws.ec2.vpcs.modifyAttribute, { path: "/ec2/vpcs/:vpcId/attributes", method: "PUT" }], [apiEndpointKeys.aws.ec2.subnets.list, { path: "/ec2/subnets", method: "GET" }], [apiEndpointKeys.aws.ec2.subnets.create, { path: "/ec2/subnets", method: "POST" }], [apiEndpointKeys.aws.ec2.subnets.delete, { path: "/ec2/subnets/:subnetId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.subnets.modifyAttribute, { path: "/ec2/subnets/:subnetId/attributes", method: "PUT" }], [apiEndpointKeys.aws.ec2.internetGateways.list, { path: "/ec2/internet-gateways", method: "GET" }], [apiEndpointKeys.aws.ec2.internetGateways.create, { path: "/ec2/internet-gateways", method: "POST" }], [apiEndpointKeys.aws.ec2.internetGateways.attach, { path: "/ec2/internet-gateways/:igwId/attach", method: "POST" }], [apiEndpointKeys.aws.ec2.internetGateways.detach, { path: "/ec2/internet-gateways/:igwId/detach", method: "POST" }], [apiEndpointKeys.aws.ec2.internetGateways.delete, { path: "/ec2/internet-gateways/:igwId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.natGateways.list, { path: "/ec2/nat-gateways", method: "GET" }], [apiEndpointKeys.aws.ec2.natGateways.create, { path: "/ec2/nat-gateways", method: "POST" }], [apiEndpointKeys.aws.ec2.natGateways.delete, { path: "/ec2/nat-gateways/:natId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.routeTables.list, { path: "/ec2/route-tables", method: "GET" }], [apiEndpointKeys.aws.ec2.routeTables.create, { path: "/ec2/route-tables", method: "POST" }], [apiEndpointKeys.aws.ec2.routeTables.delete, { path: "/ec2/route-tables/:rtbId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.routeTables.createRoute, { path: "/ec2/route-tables/:rtbId/routes", method: "POST" }], [apiEndpointKeys.aws.ec2.routeTables.deleteRoute, { path: "/ec2/route-tables/:rtbId/routes", method: "DELETE" }], [apiEndpointKeys.aws.ec2.routeTables.associate, { path: "/ec2/route-tables/:rtbId/associations", method: "POST" }], [apiEndpointKeys.aws.ec2.routeTables.disassociate,{ path: "/ec2/route-table-associations/:associationId", method: "DELETE" }], [apiEndpointKeys.aws.ec2.elasticIps.list, { path: "/ec2/elastic-ips", method: "GET" }], [apiEndpointKeys.aws.ec2.elasticIps.create, { path: "/ec2/elastic-ips", method: "POST" }], [apiEndpointKeys.aws.ec2.elasticIps.release, { path: "/ec2/elastic-ips/:allocationId/release", method: "POST" }], [apiEndpointKeys.aws.ec2.elasticIps.associate, { path: "/ec2/elastic-ips/:allocationId/associate", method: "POST" }], [apiEndpointKeys.aws.ec2.elasticIps.disassociate, { path: "/ec2/elastic-ips/:allocationId/disassociate", method: "POST" }], [apiEndpointKeys.aws.ec2.availabilityZones, { path: "/ec2/availability-zones", method: "GET" }], [apiEndpointKeys.aws.ec2.instanceTypes, { path: "/ec2/instance-types", method: "GET" }], [apiEndpointKeys.aws.ec2.vpcWizard, { path: "/ec2/vpc-wizard", method: "POST" }], ]); // ─── Client Factory ─────────────────────────────────────────────────────────── export function createApiClient( getToken?: () => string | null | Promise, ) { const client = new HttpClient( { baseUrl: API_BASE_URL, defaultHeaders: { Accept: "application/json" }, timeout: 10_000, }, endpointRegistry, ); // Account scope — every request carries the active AWS account so Floci can // isolate resources per account (the API maps this header to its SDK creds). client.addRequestInterceptor((url, init) => { const headers = (init.headers ?? {}) as Record; headers[ACCOUNT_HEADER] = getAccountId(); init.headers = headers; return { url, init }; }); client.addRequestInterceptor((url, init) => { if (!['POST', 'PUT', 'PATCH', 'DELETE'].includes(init.method ?? 'GET')) return {url, init}; const csrf = document.cookie.split('; ').find((item) => item.startsWith('floci_ui_csrf='))?.split('=')[1]; if (csrf) (init.headers as Record)['X-Floci-CSRF'] = decodeURIComponent(csrf); return {url, init}; }); // Auth interceptor — attaches Bearer token if available if (getToken) { client.addRequestInterceptor(async (url, init) => { const token = await getToken(); if (token) { (init.headers as Record)["Authorization"] = `Bearer ${token}`; } return { url, init }; }); } // Logging interceptor (dev only) if (import.meta.env.DEV) { client.addResponseInterceptor((res) => { console.debug(`[HTTP] ${res.status} ${res.url}`); return res; }); } client.addResponseInterceptor((res) => { if (res.status === 401 && !res.url.includes('/api/auth/')) { const returnTo = `${window.location.pathname}${window.location.search}`; window.location.assign(`/login?returnTo=${encodeURIComponent(returnTo)}`); } return res; }); return client; } export const apiClient = createApiClient();