import * as HttpClient from "effect/unstable/http/HttpClient";
import * as S from "effect/Schema";
import * as stream from "effect/Stream";
import * as API from "../client/api.js";
import * as T from "../traits.js";
import * as C from "../category.js";
const svc = T.AwsApiService({ sdkId: "DSQL", serviceShapeName: "DSQL" });
const auth = T.AwsAuthSigv4({ name: "dsql" });
const ver = T.ServiceVersion("2018-05-10");
const proto = T.AwsProtocolsRestJson1();
const rules = T.EndpointResolver((p, _) => {
    const { UseFIPS = false, Endpoint, Region } = p;
    const e = (u, p = {}, h = {}) => ({
        type: "endpoint",
        endpoint: { url: u, properties: p, headers: h },
    });
    const err = (m) => ({
        type: "error",
        message: m,
    });
    if (Endpoint != null) {
        if (UseFIPS === true) {
            return err("Invalid Configuration: FIPS and custom endpoint are not supported");
        }
        return e(Endpoint);
    }
    if (Region != null) {
        {
            const PartitionResult = _.partition(Region);
            if (PartitionResult != null && PartitionResult !== false) {
                if (UseFIPS === true) {
                    return e(`https://dsql-fips.${Region}.${_.getAttr(PartitionResult, "dualStackDnsSuffix")}`);
                }
                return e(`https://dsql.${Region}.${_.getAttr(PartitionResult, "dualStackDnsSuffix")}`);
            }
        }
    }
    return err("Invalid Configuration: Missing Region");
});
export const ListTagsForResourceInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ resourceArn: S.String.pipe(T.HttpLabel("resourceArn")) }).pipe(T.all(T.Http({ method: "GET", uri: "/tags/{resourceArn}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "ListTagsForResourceInput",
});
export const TagMap = /*@__PURE__*/ /*#__PURE__*/ S.Record(S.String, S.String.pipe(S.optional));
export const ListTagsForResourceOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ tags: S.optional(TagMap) })).annotate({
    identifier: "ListTagsForResourceOutput",
});
export const TagResourceInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    resourceArn: S.String.pipe(T.HttpLabel("resourceArn")),
    tags: TagMap,
}).pipe(T.all(T.Http({ method: "POST", uri: "/tags/{resourceArn}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "TagResourceInput",
});
export const TagResourceResponse = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({})).annotate({
    identifier: "TagResourceResponse",
});
export const TagKeyList = /*@__PURE__*/ /*#__PURE__*/ S.Array(S.String);
export const UntagResourceInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    resourceArn: S.String.pipe(T.HttpLabel("resourceArn")),
    tagKeys: TagKeyList.pipe(T.HttpQuery("tagKeys")),
}).pipe(T.all(T.Http({ method: "DELETE", uri: "/tags/{resourceArn}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "UntagResourceInput",
});
export const UntagResourceResponse = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({})).annotate({
    identifier: "UntagResourceResponse",
});
export const ClusterArnList = /*@__PURE__*/ /*#__PURE__*/ S.Array(S.String);
export const MultiRegionProperties = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    witnessRegion: S.optional(S.String),
    clusters: S.optional(ClusterArnList),
})).annotate({
    identifier: "MultiRegionProperties",
});
export const CreateClusterInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    deletionProtectionEnabled: S.optional(S.Boolean),
    kmsEncryptionKey: S.optional(S.String),
    tags: S.optional(TagMap),
    clientToken: S.optional(S.String).pipe(T.IdempotencyToken()),
    multiRegionProperties: S.optional(MultiRegionProperties),
    policy: S.optional(S.String),
    bypassPolicyLockoutSafetyCheck: S.optional(S.Boolean),
}).pipe(T.all(T.Http({ method: "POST", uri: "/cluster" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "CreateClusterInput",
});
export const ClusterStatus = /*@__PURE__*/ /*#__PURE__*/ S.String;
export const EncryptionType = /*@__PURE__*/ /*#__PURE__*/ S.String;
export const EncryptionStatus = /*@__PURE__*/ /*#__PURE__*/ S.String;
export const EncryptionDetails = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    encryptionType: EncryptionType,
    kmsKeyArn: S.optional(S.String),
    encryptionStatus: EncryptionStatus,
})).annotate({
    identifier: "EncryptionDetails",
});
export const CreateClusterOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String,
    arn: S.String,
    status: ClusterStatus,
    creationTime: S.Date.pipe(T.TimestampFormat("epoch-seconds")),
    multiRegionProperties: S.optional(MultiRegionProperties),
    encryptionDetails: S.optional(EncryptionDetails),
    deletionProtectionEnabled: S.Boolean,
    endpoint: S.optional(S.String),
})).annotate({
    identifier: "CreateClusterOutput",
});
export const ValidationExceptionReason = /*@__PURE__*/ /*#__PURE__*/ S.String;
export const ValidationExceptionField = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ name: S.String, message: S.String })).annotate({
    identifier: "ValidationExceptionField",
});
export const ValidationExceptionFieldList = /*@__PURE__*/ /*#__PURE__*/ S.Array(ValidationExceptionField);
export const GetClusterInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ identifier: S.String.pipe(T.HttpLabel("identifier")) }).pipe(T.all(T.Http({ method: "GET", uri: "/cluster/{identifier}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "GetClusterInput",
});
export const GetClusterOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String,
    arn: S.String,
    status: ClusterStatus,
    creationTime: S.Date.pipe(T.TimestampFormat("epoch-seconds")),
    deletionProtectionEnabled: S.Boolean,
    multiRegionProperties: S.optional(MultiRegionProperties),
    tags: S.optional(TagMap),
    encryptionDetails: S.optional(EncryptionDetails),
    endpoint: S.optional(S.String),
})).annotate({
    identifier: "GetClusterOutput",
});
export const UpdateClusterInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String.pipe(T.HttpLabel("identifier")),
    deletionProtectionEnabled: S.optional(S.Boolean),
    kmsEncryptionKey: S.optional(S.String),
    clientToken: S.optional(S.String).pipe(T.IdempotencyToken()),
    multiRegionProperties: S.optional(MultiRegionProperties),
}).pipe(T.all(T.Http({ method: "POST", uri: "/cluster/{identifier}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "UpdateClusterInput",
});
export const UpdateClusterOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String,
    arn: S.String,
    status: ClusterStatus,
    creationTime: S.Date.pipe(T.TimestampFormat("epoch-seconds")),
})).annotate({
    identifier: "UpdateClusterOutput",
});
export const DeleteClusterInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String.pipe(T.HttpLabel("identifier")),
    clientToken: S.optional(S.String).pipe(T.HttpQuery("client-token"), T.IdempotencyToken()),
}).pipe(T.all(T.Http({ method: "DELETE", uri: "/cluster/{identifier}" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "DeleteClusterInput",
});
export const DeleteClusterOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String,
    arn: S.String,
    status: ClusterStatus,
    creationTime: S.Date.pipe(T.TimestampFormat("epoch-seconds")),
})).annotate({
    identifier: "DeleteClusterOutput",
});
export const ListClustersInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    maxResults: S.optional(S.Number).pipe(T.HttpQuery("max-results")),
    nextToken: S.optional(S.String).pipe(T.HttpQuery("next-token")),
}).pipe(T.all(T.Http({ method: "GET", uri: "/cluster" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "ListClustersInput",
});
export const ClusterSummary = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ identifier: S.String, arn: S.String })).annotate({ identifier: "ClusterSummary" });
export const ClusterList = /*@__PURE__*/ /*#__PURE__*/ S.Array(ClusterSummary);
export const ListClustersOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ nextToken: S.optional(S.String), clusters: ClusterList })).annotate({
    identifier: "ListClustersOutput",
});
export const DeleteClusterPolicyInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String.pipe(T.HttpLabel("identifier")),
    expectedPolicyVersion: S.optional(S.String).pipe(T.HttpQuery("expected-policy-version")),
    clientToken: S.optional(S.String).pipe(T.HttpQuery("client-token"), T.IdempotencyToken()),
}).pipe(T.all(T.Http({ method: "DELETE", uri: "/cluster/{identifier}/policy" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "DeleteClusterPolicyInput",
});
export const DeleteClusterPolicyOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ policyVersion: S.String })).annotate({
    identifier: "DeleteClusterPolicyOutput",
});
export const GetClusterPolicyInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ identifier: S.String.pipe(T.HttpLabel("identifier")) }).pipe(T.all(T.Http({ method: "GET", uri: "/cluster/{identifier}/policy" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "GetClusterPolicyInput",
});
export const GetClusterPolicyOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ policy: S.String, policyVersion: S.String })).annotate({
    identifier: "GetClusterPolicyOutput",
});
export const GetVpcEndpointServiceNameInput = 
/*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ identifier: S.String.pipe(T.HttpLabel("identifier")) }).pipe(T.all(T.Http({
    method: "GET",
    uri: "/clusters/{identifier}/vpc-endpoint-service-name",
}), svc, auth, proto, ver, rules))).annotate({
    identifier: "GetVpcEndpointServiceNameInput",
});
export const GetVpcEndpointServiceNameOutput = 
/*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    serviceName: S.String,
    clusterVpcEndpoint: S.optional(S.String),
})).annotate({
    identifier: "GetVpcEndpointServiceNameOutput",
});
export const PutClusterPolicyInput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({
    identifier: S.String.pipe(T.HttpLabel("identifier")),
    policy: S.String,
    bypassPolicyLockoutSafetyCheck: S.optional(S.Boolean),
    expectedPolicyVersion: S.optional(S.String),
    clientToken: S.optional(S.String).pipe(T.IdempotencyToken()),
}).pipe(T.all(T.Http({ method: "POST", uri: "/cluster/{identifier}/policy" }), svc, auth, proto, ver, rules))).annotate({
    identifier: "PutClusterPolicyInput",
});
export const PutClusterPolicyOutput = /*@__PURE__*/ /*#__PURE__*/ S.suspend(() => S.Struct({ policyVersion: S.String })).annotate({
    identifier: "PutClusterPolicyOutput",
});
//# Errors
export class ResourceNotFoundException extends S.TaggedErrorClass()("ResourceNotFoundException", { message: S.String, resourceId: S.String, resourceType: S.String }).pipe(C.withBadRequestError) {
}
export class ServiceQuotaExceededException extends S.TaggedErrorClass()("ServiceQuotaExceededException", {
    message: S.String,
    resourceId: S.String,
    resourceType: S.String,
    serviceCode: S.String,
    quotaCode: S.String,
}).pipe(C.withQuotaError) {
}
export class ConflictException extends S.TaggedErrorClass()("ConflictException", {
    message: S.String,
    resourceId: S.optional(S.String),
    resourceType: S.optional(S.String),
}).pipe(C.withConflictError) {
}
export class ValidationException extends S.TaggedErrorClass()("ValidationException", {
    message: S.String,
    reason: ValidationExceptionReason,
    fieldList: S.optional(ValidationExceptionFieldList),
}).pipe(C.withBadRequestError) {
}
export class InternalServerException extends S.TaggedErrorClass()("InternalServerException", {
    message: S.String,
    retryAfterSeconds: S.optional(S.Number).pipe(T.HttpHeader("Retry-After")),
}, T.Retryable()).pipe(C.withServerError, C.withRetryableError) {
}
export class ThrottlingException extends S.TaggedErrorClass()("ThrottlingException", {
    message: S.String,
    serviceCode: S.optional(S.String),
    quotaCode: S.optional(S.String),
    retryAfterSeconds: S.optional(S.Number).pipe(T.HttpHeader("Retry-After")),
}, T.Retryable({ throttling: true })).pipe(C.withThrottlingError, C.withRetryableError) {
}
/**
 * Lists all of the tags for a resource.
 */
export const listTagsForResource = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: ListTagsForResourceInput,
    output: ListTagsForResourceOutput,
    errors: [ResourceNotFoundException],
}));
/**
 * Tags a resource with a map of key and value pairs.
 */
export const tagResource = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: TagResourceInput,
    output: TagResourceResponse,
    errors: [ResourceNotFoundException, ServiceQuotaExceededException],
}));
/**
 * Removes a tag from a resource.
 */
export const untagResource = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: UntagResourceInput,
    output: UntagResourceResponse,
    errors: [ResourceNotFoundException],
}));
/**
 * The CreateCluster API allows you to create both single-Region clusters and multi-Region clusters. With the addition of the *multiRegionProperties* parameter, you can create a cluster with witness Region support and establish peer relationships with clusters in other Regions during creation.
 *
 * Creating multi-Region clusters requires additional IAM permissions beyond those needed for single-Region clusters, as detailed in the **Required permissions** section below.
 *
 * **Required permissions**
 *
 * ### dsql:CreateCluster
 *
 * Required to create a cluster.
 *
 * Resources: `arn:aws:dsql:region:account-id:cluster/*`
 *
 * ### dsql:TagResource
 *
 * Permission to add tags to a resource.
 *
 * Resources: `arn:aws:dsql:region:account-id:cluster/*`
 *
 * ### dsql:PutMultiRegionProperties
 *
 * Permission to configure multi-Region properties for a cluster.
 *
 * Resources: `arn:aws:dsql:region:account-id:cluster/*`
 *
 * ### dsql:AddPeerCluster
 *
 * When specifying `multiRegionProperties.clusters`, permission to add peer clusters.
 *
 * Resources:
 *
 * - Local cluster: `arn:aws:dsql:region:account-id:cluster/*`
 *
 * - Each peer cluster: exact ARN of each specified peer cluster
 *
 * ### dsql:PutWitnessRegion
 *
 * When specifying `multiRegionProperties.witnessRegion`, permission to set a witness Region. This permission is checked both in the cluster Region and in the witness Region.
 *
 * Resources: `arn:aws:dsql:region:account-id:cluster/*`
 *
 * Condition Keys: `dsql:WitnessRegion` (matching the specified witness region)
 *
 * - The witness Region specified in `multiRegionProperties.witnessRegion` cannot be the same as the cluster's Region.
 */
export const createCluster = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: CreateClusterInput,
    output: CreateClusterOutput,
    errors: [
        ConflictException,
        ServiceQuotaExceededException,
        ValidationException,
    ],
}));
/**
 * Retrieves information about a cluster.
 */
export const getCluster = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: GetClusterInput,
    output: GetClusterOutput,
    errors: [ResourceNotFoundException],
}));
/**
 * The *UpdateCluster* API allows you to modify both single-Region and multi-Region cluster configurations. With the *multiRegionProperties* parameter, you can add or modify witness Region support and manage peer relationships with clusters in other Regions.
 *
 * Note that updating multi-Region clusters requires additional IAM permissions beyond those needed for standard cluster updates, as detailed in the Permissions section.
 *
 * **Required permissions**
 *
 * ### dsql:UpdateCluster
 *
 * Permission to update a DSQL cluster.
 *
 * Resources: `arn:aws:dsql:*region*:*account-id*:cluster/*cluster-id* `
 *
 * ### dsql:PutMultiRegionProperties
 *
 * Permission to configure multi-Region properties for a cluster.
 *
 * Resources: `arn:aws:dsql:*region*:*account-id*:cluster/*cluster-id* `
 *
 * ### dsql:GetCluster
 *
 * Permission to retrieve cluster information.
 *
 * Resources: `arn:aws:dsql:*region*:*account-id*:cluster/*cluster-id* `
 *
 * ### dsql:AddPeerCluster
 *
 * Permission to add peer clusters.
 *
 * Resources:
 *
 * - Local cluster: `arn:aws:dsql:*region*:*account-id*:cluster/*cluster-id* `
 *
 * - Each peer cluster: exact ARN of each specified peer cluster
 *
 * ### dsql:RemovePeerCluster
 *
 * Permission to remove peer clusters. The *dsql:RemovePeerCluster* permission uses a wildcard ARN pattern to simplify permission management during updates.
 *
 * Resources: `arn:aws:dsql:*:*account-id*:cluster/*`
 *
 * ### dsql:PutWitnessRegion
 *
 * Permission to set a witness Region.
 *
 * Resources: `arn:aws:dsql:*region*:*account-id*:cluster/*cluster-id* `
 *
 * Condition Keys: dsql:WitnessRegion (matching the specified witness Region)
 *
 * **This permission is checked both in the cluster Region and in the witness Region.**
 *
 * - The witness region specified in `multiRegionProperties.witnessRegion` cannot be the same as the cluster's Region.
 *
 * - When updating clusters with peer relationships, permissions are checked for both adding and removing peers.
 *
 * - The `dsql:RemovePeerCluster` permission uses a wildcard ARN pattern to simplify permission management during updates.
 */
export const updateCluster = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: UpdateClusterInput,
    output: UpdateClusterOutput,
    errors: [ConflictException, ResourceNotFoundException, ValidationException],
}));
/**
 * Deletes a cluster in Amazon Aurora DSQL.
 */
export const deleteCluster = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: DeleteClusterInput,
    output: DeleteClusterOutput,
    errors: [ConflictException, ResourceNotFoundException],
}));
/**
 * Retrieves information about a list of clusters.
 */
export const listClusters = /*@__PURE__*/ /*#__PURE__*/ API.makePaginated(() => ({
    input: ListClustersInput,
    output: ListClustersOutput,
    errors: [ResourceNotFoundException],
    pagination: {
        inputToken: "nextToken",
        outputToken: "nextToken",
        items: "clusters",
        pageSize: "maxResults",
    },
}));
/**
 * Deletes the resource-based policy attached to a cluster. This removes all access permissions defined by the policy, reverting to default access controls.
 */
export const deleteClusterPolicy = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: DeleteClusterPolicyInput,
    output: DeleteClusterPolicyOutput,
    errors: [ConflictException, ResourceNotFoundException, ValidationException],
}));
/**
 * Retrieves the resource-based policy document attached to a cluster. This policy defines the access permissions and conditions for the cluster.
 */
export const getClusterPolicy = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: GetClusterPolicyInput,
    output: GetClusterPolicyOutput,
    errors: [ResourceNotFoundException, ValidationException],
}));
/**
 * Retrieves the VPC endpoint service name.
 */
export const getVpcEndpointServiceName = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: GetVpcEndpointServiceNameInput,
    output: GetVpcEndpointServiceNameOutput,
    errors: [
        InternalServerException,
        ResourceNotFoundException,
        ThrottlingException,
        ValidationException,
    ],
}));
/**
 * Attaches a resource-based policy to a cluster. This policy defines access permissions and conditions for the cluster, allowing you to control which principals can perform actions on the cluster.
 */
export const putClusterPolicy = /*@__PURE__*/ /*#__PURE__*/ API.make(() => ({
    input: PutClusterPolicyInput,
    output: PutClusterPolicyOutput,
    errors: [ConflictException, ResourceNotFoundException, ValidationException],
}));
//# sourceMappingURL=dsql.js.map