"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentCoreMcpRuntimeToolSchema = exports.McpRuntimeBindingSchema = exports.AgentCoreGatewaySchema = exports.GatewayPolicyEngineConfigurationSchema = exports.PolicyEngineModeSchema = exports.GatewayExceptionLevelSchema = exports.AgentCoreGatewayTargetSchema = exports.SchemaSourceSchema = exports.ToolComputeConfigSchema = exports.RuntimeConfigSchema = exports.IamPolicyDocumentSchema = exports.ToolImplementationBindingSchema = exports.ComputeHostSchema = exports.McpImplLanguageSchema = exports.LambdaFunctionArnConfigSchema = exports.ApiGatewayConfigSchema = exports.ApiGatewayToolConfigurationSchema = exports.ApiGatewayToolOverrideSchema = exports.ApiGatewayToolFilterSchema = exports.ApiGatewayHttpMethodSchema = exports.TARGET_TYPE_AUTH_CONFIG = exports.OutboundAuthSchema = exports.OutboundAuthTypeSchema = exports.GatewayTargetTypeSchema = void 0;
const constants_1 = require("../constants");
const agent_env_1 = require("./agent-env");
const auth_1 = require("./auth");
const mcp_defs_1 = require("./mcp-defs");
const tags_1 = require("./primitives/tags");
const zod_1 = require("zod");
// ============================================================================
// MCP-Specific Schemas
// ============================================================================
exports.GatewayTargetTypeSchema = zod_1.z.enum([
    'lambda',
    'mcpServer',
    'openApiSchema',
    'smithyModel',
    'apiGateway',
    'lambdaFunctionArn',
]);
// ============================================================================
// Gateway Authorization Schemas
// ============================================================================
// Auth schemas (GatewayAuthorizerTypeSchema, CustomJwtAuthorizerConfigSchema, etc.)
// are defined in ./auth.ts and exported via the barrel (index.ts).
exports.OutboundAuthTypeSchema = zod_1.z.enum(['OAUTH', 'API_KEY', 'NONE']);
exports.OutboundAuthSchema = zod_1.z
    .object({
    type: exports.OutboundAuthTypeSchema.default('NONE'),
    credentialName: zod_1.z.string().min(1).optional(),
    scopes: zod_1.z.array(zod_1.z.string()).optional(),
})
    .strict();
// ============================================================================
// Target Type → Auth Rules (single source of truth)
// ============================================================================
/**
 * Outbound authentication rules per gateway target type.
 *
 * - `authRequired` — target cannot be created without outbound auth
 * - `validAuthTypes` — allowed OutboundAuthType values (empty = no outbound auth applicable)
 * - `iamRoleFallback` — CDK passes GATEWAY_IAM_ROLE when no auth configured
 */
exports.TARGET_TYPE_AUTH_CONFIG = {
    openApiSchema: { authRequired: true, validAuthTypes: ['OAUTH', 'API_KEY'], iamRoleFallback: false },
    smithyModel: { authRequired: false, validAuthTypes: [], iamRoleFallback: true },
    apiGateway: { authRequired: false, validAuthTypes: ['API_KEY', 'NONE'], iamRoleFallback: true },
    mcpServer: { authRequired: false, validAuthTypes: ['OAUTH', 'NONE'], iamRoleFallback: false },
    lambda: { authRequired: false, validAuthTypes: ['OAUTH', 'NONE'], iamRoleFallback: true },
    lambdaFunctionArn: { authRequired: false, validAuthTypes: ['OAUTH', 'NONE'], iamRoleFallback: true },
};
// ============================================================================
// API Gateway Target Schemas
// ============================================================================
exports.ApiGatewayHttpMethodSchema = zod_1.z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']);
exports.ApiGatewayToolFilterSchema = zod_1.z
    .object({
    filterPath: zod_1.z.string().min(1),
    methods: zod_1.z.array(exports.ApiGatewayHttpMethodSchema).min(1),
})
    .strict();
exports.ApiGatewayToolOverrideSchema = zod_1.z
    .object({
    name: zod_1.z.string().min(1),
    path: zod_1.z.string().min(1),
    method: exports.ApiGatewayHttpMethodSchema,
    description: zod_1.z.string().optional(),
})
    .strict();
exports.ApiGatewayToolConfigurationSchema = zod_1.z
    .object({
    toolFilters: zod_1.z.array(exports.ApiGatewayToolFilterSchema).min(1),
    toolOverrides: zod_1.z.array(exports.ApiGatewayToolOverrideSchema).optional(),
})
    .strict();
exports.ApiGatewayConfigSchema = zod_1.z
    .object({
    restApiId: zod_1.z.string().min(1),
    stage: zod_1.z.string().min(1),
    apiGatewayToolConfiguration: exports.ApiGatewayToolConfigurationSchema,
})
    .strict();
exports.LambdaFunctionArnConfigSchema = zod_1.z
    .object({
    lambdaArn: zod_1.z.string().min(1).max(170),
    toolSchemaFile: zod_1.z.string().min(1),
})
    .strict();
exports.McpImplLanguageSchema = zod_1.z.enum(['TypeScript', 'Python']);
exports.ComputeHostSchema = zod_1.z.enum(['Lambda', 'AgentCoreRuntime']);
// ============================================================================
// Branded Path Schemas
// ============================================================================
// Branded path schemas - cast string output to branded path types
const DirectoryPathSchema = zod_1.z.string().min(1);
// ============================================================================
// Tool Implementation Binding
// ============================================================================
/**
 * Code-based tool implementation (Python, TypeScript).
 *
 * The CLI is responsible for:
 * - installing dependencies
 * - building / bundling
 * - creating a zip artifact
 * - uploading artifacts to S3
 */
exports.ToolImplementationBindingSchema = zod_1.z
    .object({
    language: zod_1.z.enum(['TypeScript', 'Python']),
    path: zod_1.z.string().min(1),
    handler: zod_1.z.string().min(1),
})
    .strict();
// ============================================================================
// IAM Policy Document
// ============================================================================
/**
 * Opaque IAM policy document.
 *
 * This is passed through verbatim to CloudFormation / IAM.
 * AgentCore does not validate, transform, or provide compatibility guarantees.
 */
exports.IamPolicyDocumentSchema = zod_1.z
    .object({
    Version: zod_1.z.string(),
    Statement: zod_1.z.array(zod_1.z.unknown()),
})
    .passthrough(); // Allow additional IAM policy fields
// ============================================================================
// Runtime Configuration
// ============================================================================
/**
 * AgentCore Runtime name validation.
 * Pattern: [a-zA-Z][a-zA-Z0-9_]{0,47}
 * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-bedrockagentcore-runtime.html#cfn-bedrockagentcore-runtime-agentruntimename
 */
const AgentRuntimeNameSchema = zod_1.z
    .string()
    .min(1)
    .max(48)
    .regex(/^[a-zA-Z][a-zA-Z0-9_]{0,47}$/, 'Must begin with a letter and contain only alphanumeric characters and underscores (max 48 chars)');
/**
 * Python entrypoint validation for Runtime codeConfiguration.
 * Format: "file.py" or "file.py:handler" or "path/file.py:handler"
 */
const PythonEntrypointSchema = zod_1.z
    .string()
    .min(1)
    .regex(
// eslint-disable-next-line security/detect-unsafe-regex -- character class quantifiers don't cause backtracking
/^[a-zA-Z0-9_][a-zA-Z0-9_/.-]*\.py(:[a-zA-Z_][a-zA-Z0-9_]*)?$/, 'Must be a Python file path with optional handler (e.g., "main.py:agent" or "src/handler.py:app")');
/**
 * Instrumentation configuration for runtime observability.
 */
const InstrumentationSchema = zod_1.z.object({
    /**
     * Enable OpenTelemetry instrumentation using opentelemetry-distro.
     * When enabled, the runtime entrypoint is wrapped with opentelemetry-instrument.
     * Defaults to true for new runtimes.
     */
    enableOtel: zod_1.z.boolean().default(true),
});
const CodeZipRuntimeConfigSchema = zod_1.z
    .object({
    artifact: zod_1.z.literal('CodeZip'),
    pythonVersion: constants_1.PythonRuntimeSchema,
    name: AgentRuntimeNameSchema,
    entrypoint: PythonEntrypointSchema,
    codeLocation: DirectoryPathSchema,
    /** Instrumentation settings for observability. Defaults to OTel enabled. */
    instrumentation: InstrumentationSchema.optional(),
    networkMode: constants_1.NetworkModeSchema.optional().default('PUBLIC'),
    description: zod_1.z.string().optional(),
})
    .strict();
/**
 * Runtime configuration for AgentCore Runtime (MCP mode).
 * Explicit CodeZip artifact configuration - no CLI-managed defaults.
 */
exports.RuntimeConfigSchema = CodeZipRuntimeConfigSchema;
// ============================================================================
// Compute Configuration
// ============================================================================
/**
 * Lambda compute configuration schema.
 * Lambda supports both Python and TypeScript.
 */
const LambdaComputeConfigSchema = zod_1.z
    .object({
    host: zod_1.z.literal('Lambda'),
    implementation: exports.ToolImplementationBindingSchema,
    nodeVersion: constants_1.NodeRuntimeSchema.optional(),
    pythonVersion: constants_1.PythonRuntimeSchema.optional(),
    timeout: zod_1.z.number().int().min(1).max(900).optional(),
    memorySize: zod_1.z.number().int().min(128).max(10240).optional(),
    iamPolicy: exports.IamPolicyDocumentSchema.optional(),
})
    .strict()
    .refine(data => {
    // TypeScript requires nodeVersion
    if (data.implementation.language === 'TypeScript' && !data.nodeVersion) {
        return false;
    }
    // Python requires pythonVersion
    if (data.implementation.language === 'Python' && !data.pythonVersion) {
        return false;
    }
    // Other (container) does not require runtime version - uses container image
    return true;
}, {
    message: 'TypeScript Lambda must specify nodeVersion, Python Lambda must specify pythonVersion',
});
/**
 * AgentCore Runtime compute configuration schema.
 * AgentCore Runtime ONLY supports Python.
 */
const AgentCoreRuntimeComputeConfigSchema = zod_1.z
    .object({
    host: zod_1.z.literal('AgentCoreRuntime'),
    implementation: exports.ToolImplementationBindingSchema,
    runtime: exports.RuntimeConfigSchema.optional(),
    iamPolicy: exports.IamPolicyDocumentSchema.optional(),
})
    .strict()
    .refine(data => data.implementation.language === 'Python', {
    message: 'AgentCore Runtime only supports Python',
});
/**
 * Tool compute configuration (discriminated union).
 */
exports.ToolComputeConfigSchema = zod_1.z.discriminatedUnion('host', [
    LambdaComputeConfigSchema,
    AgentCoreRuntimeComputeConfigSchema,
]);
// ============================================================================
// Schema Source (for OpenAPI / Smithy targets)
// ============================================================================
/** S3 reference for an API schema file. */
const SchemaS3SourceSchema = zod_1.z
    .object({
    uri: zod_1.z.string().min(1).startsWith('s3://'),
    bucketOwnerAccountId: zod_1.z.string().optional(),
})
    .strict();
/** Inline (local file) reference for an API schema file. Path is relative to project root. */
const SchemaInlineSourceSchema = zod_1.z
    .object({
    path: zod_1.z.string().min(1),
})
    .strict();
/** Schema source: either a local file path (read at synth time) or an S3 URI. */
exports.SchemaSourceSchema = zod_1.z.union([
    zod_1.z.object({ inline: SchemaInlineSourceSchema }).strict(),
    zod_1.z.object({ s3: SchemaS3SourceSchema }).strict(),
]);
// ============================================================================
// Gateway Target
// ============================================================================
/**
 * A gateway target binds one or more ToolDefinitions to compute that services them.
 *
 * A single Lambda or AgentCoreRuntime can expose multiple tools. The gateway routes
 * tool invocations to the appropriate target based on tool name.
 *
 * If compute is omitted, the tools are treated as external or abstract targets.
 */
exports.AgentCoreGatewayTargetSchema = zod_1.z
    .object({
    name: zod_1.z.string().min(1),
    targetType: exports.GatewayTargetTypeSchema,
    /** Tool definitions. Required for Lambda targets. Optional for MCP Server (discovered via tools/list). */
    toolDefinitions: zod_1.z.array(mcp_defs_1.ToolDefinitionSchema).optional(),
    /** Compute configuration. Required for Lambda/Runtime scaffold targets. */
    compute: exports.ToolComputeConfigSchema.optional(),
    /** MCP Server endpoint URL. Required for external MCP Server targets. */
    endpoint: zod_1.z.string().url().optional(),
    /** Outbound auth configuration for the target. */
    outboundAuth: exports.OutboundAuthSchema.optional(),
    /** API Gateway configuration. Required for apiGateway target type. */
    apiGateway: exports.ApiGatewayConfigSchema.optional(),
    /** Schema source for openApiSchema / smithyModel targets. */
    schemaSource: exports.SchemaSourceSchema.optional(),
    /** Lambda Function ARN configuration. Required for lambdaFunctionArn target type. */
    lambdaFunctionArn: exports.LambdaFunctionArnConfigSchema.optional(),
})
    .strict()
    .superRefine((data, ctx) => {
    if (data.targetType === 'apiGateway') {
        if (!data.apiGateway) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'apiGateway config is required for apiGateway target type',
                path: ['apiGateway'],
            });
        }
        if (data.compute) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'compute is not applicable for apiGateway target type',
                path: ['compute'],
            });
        }
        if (data.endpoint) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'endpoint is not applicable for apiGateway target type',
                path: ['endpoint'],
            });
        }
        if (data.toolDefinitions && data.toolDefinitions.length > 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'toolDefinitions is not applicable for apiGateway target type (tools are auto-discovered)',
                path: ['toolDefinitions'],
            });
        }
        if (data.lambdaFunctionArn) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'lambdaFunctionArn is not applicable for apiGateway target type',
                path: ['lambdaFunctionArn'],
            });
        }
    }
    if (data.targetType === 'openApiSchema' || data.targetType === 'smithyModel') {
        if (!data.schemaSource) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: `${data.targetType} targets require a schemaSource.`,
                path: ['schemaSource'],
            });
        }
        if (data.compute) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: `compute is not applicable for ${data.targetType} target type`,
                path: ['compute'],
            });
        }
        if (data.endpoint) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: `endpoint is not applicable for ${data.targetType} target type`,
                path: ['endpoint'],
            });
        }
        if (data.toolDefinitions && data.toolDefinitions.length > 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: `toolDefinitions is not applicable for ${data.targetType} target type`,
                path: ['toolDefinitions'],
            });
        }
        if (data.apiGateway) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: `apiGateway config is not applicable for ${data.targetType} target type`,
                path: ['apiGateway'],
            });
        }
    }
    if (data.targetType === 'lambdaFunctionArn') {
        if (!data.lambdaFunctionArn) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'lambdaFunctionArn config is required for lambdaFunctionArn target type',
                path: ['lambdaFunctionArn'],
            });
        }
        if (data.compute) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'compute is not applicable for lambdaFunctionArn target type',
                path: ['compute'],
            });
        }
        if (data.endpoint) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'endpoint is not applicable for lambdaFunctionArn target type',
                path: ['endpoint'],
            });
        }
        if (data.apiGateway) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'apiGateway is not applicable for lambdaFunctionArn target type',
                path: ['apiGateway'],
            });
        }
        if (data.outboundAuth) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'outboundAuth is not applicable for lambdaFunctionArn target type',
                path: ['outboundAuth'],
            });
        }
        if (data.toolDefinitions && data.toolDefinitions.length > 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'toolDefinitions is not applicable for lambdaFunctionArn target type (tools are defined via toolSchemaFile)',
                path: ['toolDefinitions'],
            });
        }
    }
    if (data.targetType === 'mcpServer') {
        if (!data.compute && !data.endpoint) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'MCP Server targets require either an endpoint URL or compute configuration.',
            });
        }
        if (data.apiGateway) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'apiGateway is not applicable for mcpServer target type',
                path: ['apiGateway'],
            });
        }
        if (data.lambdaFunctionArn) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                message: 'lambdaFunctionArn is not applicable for mcpServer target type',
                path: ['lambdaFunctionArn'],
            });
        }
    }
    if (data.targetType === 'lambda' && !data.compute) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: 'Lambda targets require compute configuration.',
            path: ['compute'],
        });
    }
    if (data.targetType === 'lambda' && (!data.toolDefinitions || data.toolDefinitions.length === 0)) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: 'Lambda targets require at least one tool definition.',
            path: ['toolDefinitions'],
        });
    }
    // Centralized outbound auth validation (driven by TARGET_TYPE_AUTH_CONFIG)
    const authConfig = exports.TARGET_TYPE_AUTH_CONFIG[data.targetType];
    const authType = data.outboundAuth?.type ?? 'NONE';
    if (authConfig.authRequired && authType === 'NONE') {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `${data.targetType} targets require outbound auth (${authConfig.validAuthTypes.join(' or ')})`,
            path: ['outboundAuth'],
        });
    }
    if (authConfig.validAuthTypes.length === 0 && authType !== 'NONE') {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `${data.targetType} targets use IAM role auth; outboundAuth is not applicable`,
            path: ['outboundAuth'],
        });
    }
    if (authConfig.validAuthTypes.length > 0 && authType !== 'NONE' && !authConfig.validAuthTypes.includes(authType)) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `${data.targetType} targets do not support ${authType} outbound auth`,
            path: ['outboundAuth'],
        });
    }
    if (data.outboundAuth && data.outboundAuth.type !== 'NONE' && !data.outboundAuth.credentialName) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `${data.outboundAuth.type} outbound auth requires a credentialName.`,
            path: ['outboundAuth', 'credentialName'],
        });
    }
});
// ============================================================================
// Gateway Exception Level
// ============================================================================
exports.GatewayExceptionLevelSchema = zod_1.z.enum(['NONE', 'DEBUG']);
// ============================================================================
// Gateway Policy Engine Configuration
// ============================================================================
exports.PolicyEngineModeSchema = zod_1.z.enum(['LOG_ONLY', 'ENFORCE']);
exports.GatewayPolicyEngineConfigurationSchema = zod_1.z
    .object({
    policyEngineName: zod_1.z.string().min(1),
    mode: exports.PolicyEngineModeSchema,
})
    .strict();
// ============================================================================
// Gateway
// ============================================================================
/**
 * Gateway abstraction with opinionated defaults.
 * Supports NONE (default) or CUSTOM_JWT authorizer types.
 */
exports.AgentCoreGatewaySchema = zod_1.z
    .object({
    name: agent_env_1.GatewayNameSchema,
    /** Actual AWS resource name for imported gateways. When set, CDK uses this instead of generating projectName-name. */
    resourceName: agent_env_1.GatewayNameSchema.optional(),
    description: zod_1.z.string().optional(),
    targets: zod_1.z.array(exports.AgentCoreGatewayTargetSchema),
    /** Authorization type for the gateway. Defaults to 'NONE'. */
    authorizerType: auth_1.GatewayAuthorizerTypeSchema.default('NONE'),
    /** Authorizer configuration. Required when authorizerType is 'CUSTOM_JWT'. */
    authorizerConfiguration: auth_1.GatewayAuthorizerConfigSchema.optional(),
    /** Whether to enable semantic search for tool discovery. Defaults to true. */
    enableSemanticSearch: zod_1.z.boolean().default(true),
    /** Exception verbosity level. 'NONE' = generic errors (default), 'DEBUG' = verbose errors. */
    exceptionLevel: exports.GatewayExceptionLevelSchema.default('NONE'),
    /** Policy engine configuration for Cedar-based authorization of tool calls. */
    policyEngineConfiguration: exports.GatewayPolicyEngineConfigurationSchema.optional(),
    /** ARN of an existing IAM execution role. When set, CDK uses this role instead of creating a new one. */
    executionRoleArn: zod_1.z
        .string()
        .regex(/^arn:[^:]+:iam::\d{12}:role\/.+/, 'Must be a valid IAM role ARN')
        .max(2048)
        .optional(),
    tags: tags_1.TagsSchema.optional(),
})
    .strict()
    .refine(data => {
    // If authorizerType is CUSTOM_JWT, customJwtAuthorizer config must be provided
    if (data.authorizerType === 'CUSTOM_JWT') {
        return data.authorizerConfiguration?.customJwtAuthorizer !== undefined;
    }
    return true;
}, {
    message: 'customJwtAuthorizer configuration is required when authorizerType is CUSTOM_JWT',
    path: ['authorizerConfiguration'],
});
// ============================================================================
// MCP Runtime Tool
// ============================================================================
/**
 * Binding from an MCP runtime tool to a runtime.
 * When present, the runtime is granted InvokeAgentRuntime permission
 * and receives the runtime ARN in the specified environment variable.
 */
exports.McpRuntimeBindingSchema = zod_1.z
    .object({
    runtimeName: zod_1.z.string().min(1),
    envVarName: agent_env_1.EnvVarNameSchema,
})
    .strict();
/**
 * AgentCore MCP Runtime tool servers.
 *
 * These are not behind a Gateway. They are deployed as AgentCoreRuntime compute
 * and are directly addressable by agents via the generated DNS endpoint.
 *
 * Use the `bindings` array to grant agents permission to invoke this tool.
 * Each binding grants InvokeAgentRuntime permission and sets an environment variable
 * with the runtime ARN on the bound agent.
 */
exports.AgentCoreMcpRuntimeToolSchema = zod_1.z
    .object({
    name: zod_1.z.string().min(1),
    toolDefinition: mcp_defs_1.ToolDefinitionSchema,
    compute: AgentCoreRuntimeComputeConfigSchema,
    bindings: zod_1.z.array(exports.McpRuntimeBindingSchema).optional(),
})
    .strict();
//# sourceMappingURL=mcp.js.map