@@ -1,15 +0,0 @@
|
||||
import type { HttpClient } from "@effect/platform"
|
||||
|
||||
|
||||
export const BaseClientTypeId: unique symbol = Symbol.for("@effect-docker/BaseClient/BaseClient")
|
||||
export type BaseClientTypeId = typeof BaseClientTypeId
|
||||
|
||||
export interface BaseClient {
|
||||
readonly [BaseClientTypeId]: BaseClientTypeId
|
||||
readonly httpClient: HttpClient.HttpClient
|
||||
}
|
||||
|
||||
export abstract class BaseClientImpl implements BaseClient {
|
||||
readonly [BaseClientTypeId]: BaseClientTypeId = BaseClientTypeId
|
||||
constructor(readonly httpClient: HttpClient.HttpClient) {}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { type BaseClient, BaseClientImpl } from "./BaseClient.js"
|
||||
|
||||
|
||||
export * from "./gen/v1.53/index.js"
|
||||
|
||||
export const Client153TypeId: unique symbol = Symbol.for("@effect-docker/Client153/Client153")
|
||||
export type Client153TypeId = typeof Client153TypeId
|
||||
|
||||
export interface Client153 extends BaseClient {
|
||||
readonly [Client153TypeId]: Client153TypeId
|
||||
|
||||
|
||||
}
|
||||
|
||||
export class Client153Impl extends BaseClientImpl implements Client153 {
|
||||
readonly [Client153TypeId]: Client153TypeId = Client153TypeId
|
||||
}
|
||||
33
packages/effect-docker/src/Docker153Client.ts
Normal file
33
packages/effect-docker/src/Docker153Client.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { HttpClient, HttpClientRequest } from "@effect/platform"
|
||||
import { Effect } from "effect"
|
||||
import { type DockerBaseClient, DockerBaseClientImpl, type DockerClientContainerError } from "./DockerBaseClient.js"
|
||||
import type { ContainerSummary } from "./gen/v1.53/index.js"
|
||||
|
||||
|
||||
export * from "./gen/v1.53/index.js"
|
||||
|
||||
export const Docker153ClientTypeId: unique symbol = Symbol.for("@effect-docker/Docker153Client/Docker153Client")
|
||||
export type Docker153ClientTypeId = typeof Docker153ClientTypeId
|
||||
|
||||
export interface Docker153Client extends DockerBaseClient {
|
||||
readonly [Docker153ClientTypeId]: Docker153ClientTypeId
|
||||
|
||||
listContainers(): Effect.Effect<ContainerSummary, DockerClientContainerError>
|
||||
}
|
||||
|
||||
export class Docker153ClientImpl
|
||||
extends DockerBaseClientImpl
|
||||
implements Docker153Client {
|
||||
readonly [Docker153ClientTypeId]: Docker153ClientTypeId = Docker153ClientTypeId
|
||||
|
||||
listContainers() {
|
||||
return this.httpContainerClient.get("/json").pipe(
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const make: Effect.Effect<Docker153Client, never, HttpClient.HttpClient> = HttpClient.HttpClient.pipe(
|
||||
Effect.map(HttpClient.mapRequest(HttpClientRequest.prependUrl("/v1.53"))),
|
||||
Effect.map(client => new Docker153ClientImpl(client)),
|
||||
)
|
||||
70
packages/effect-docker/src/DockerBaseClient.ts
Normal file
70
packages/effect-docker/src/DockerBaseClient.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { HttpClient, type HttpClientError, HttpClientRequest } from "@effect/platform"
|
||||
import { Effect, Match, Schema } from "effect"
|
||||
|
||||
|
||||
export const DockerBaseClientTypeId: unique symbol = Symbol.for("@effect-docker/DockerBaseClient/DockerBaseClient")
|
||||
export type DockerBaseClientTypeId = typeof DockerBaseClientTypeId
|
||||
|
||||
export interface DockerBaseClient {
|
||||
readonly [DockerBaseClientTypeId]: DockerBaseClientTypeId
|
||||
|
||||
readonly httpClient: HttpClient.HttpClient.With<DockerClientError>
|
||||
readonly httpContainerClient: HttpClient.HttpClient.With<DockerClientContainerError>
|
||||
}
|
||||
|
||||
export class DockerBaseClientImpl implements DockerBaseClient {
|
||||
readonly [DockerBaseClientTypeId]: DockerBaseClientTypeId = DockerBaseClientTypeId
|
||||
|
||||
readonly httpClient: HttpClient.HttpClient.With<DockerClientError>
|
||||
readonly httpContainerClient: HttpClient.HttpClient.With<DockerClientContainerError>
|
||||
|
||||
constructor(httpClient: HttpClient.HttpClient) {
|
||||
this.httpClient = httpClient.pipe(
|
||||
HttpClient.filterStatus(status => status !== 400 && status !== 500),
|
||||
HttpClient.catchTag("ResponseError", e => Match.value(e.response.status).pipe(
|
||||
Match.when(400, () => Effect.andThen(
|
||||
e.response.json as Effect.Effect<HttpErrorResponse>,
|
||||
({ message }) => new BadParameter({ message }, true),
|
||||
)),
|
||||
Match.when(500, () => Effect.andThen(
|
||||
e.response.json as Effect.Effect<HttpErrorResponse>,
|
||||
({ message }) => new ServerError({ message }, true),
|
||||
)),
|
||||
Match.orElse(Effect.fail),
|
||||
) as Effect.Effect<never, DockerClientError>),
|
||||
)
|
||||
|
||||
this.httpContainerClient = this.httpClient.pipe(
|
||||
HttpClient.mapRequest(HttpClientRequest.appendUrl("/containers")),
|
||||
HttpClient.filterStatus(status => status !== 404),
|
||||
HttpClient.catchTag("ResponseError", e => Match.value(e.response.status).pipe(
|
||||
Match.when(404, () => Effect.andThen(
|
||||
e.response.json as Effect.Effect<HttpErrorResponse>,
|
||||
({ message }) => new NoSuchContainer({ message }, true),
|
||||
)),
|
||||
Match.orElse(Effect.fail),
|
||||
) as Effect.Effect<never, DockerClientContainerError>),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export interface HttpErrorResponse {
|
||||
readonly message: string
|
||||
}
|
||||
|
||||
|
||||
export class BadParameter extends Schema.TaggedError<BadParameter>("@effect-docker/DockerBaseClient/BadParameter")("BadParameter", {
|
||||
message: Schema.String,
|
||||
}) {}
|
||||
|
||||
export class ServerError extends Schema.TaggedError<ServerError>("@effect-docker/DockerBaseClient/ServerError")("ServerError", {
|
||||
message: Schema.String,
|
||||
}) {}
|
||||
|
||||
export type DockerClientError = HttpClientError.HttpClientError | BadParameter | ServerError
|
||||
|
||||
export class NoSuchContainer extends Schema.TaggedError<NoSuchContainer>("@effect-docker/DockerBaseClient/NoSuchContainer")("NoSuchContainer", {
|
||||
message: Schema.String,
|
||||
}) {}
|
||||
|
||||
export type DockerClientContainerError = DockerClientError | NoSuchContainer
|
||||
30
packages/effect-docker/src/test.ts
Normal file
30
packages/effect-docker/src/test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { HttpClient } from "@effect/platform"
|
||||
import { NodeHttpClient, NodeRuntime } from "@effect/platform-node"
|
||||
import { Effect, Schema } from "effect"
|
||||
|
||||
|
||||
export class NotFound extends Schema.TaggedError<NotFound>("NotFound")("NotFound", {
|
||||
message: Schema.String,
|
||||
}) {}
|
||||
|
||||
const program = Effect.gen(function*() {
|
||||
const client = yield* HttpClient.HttpClient.pipe(
|
||||
Effect.map(HttpClient.filterStatus(status => status !== 404)),
|
||||
Effect.map(HttpClient.catchTag("ResponseError", e =>
|
||||
e.response.status === 404
|
||||
? Effect.andThen(e.response.text, message => Effect.fail(new NotFound({ message: "" })))
|
||||
: Effect.fail(e)
|
||||
)),
|
||||
)
|
||||
const res = yield* client.get("https://docs.docker.com/adolf")
|
||||
console.log(res.status)
|
||||
// console.log(yield* res.text)
|
||||
|
||||
}).pipe(Effect.withSpan("program", {
|
||||
attributes: { source: "Playground" }
|
||||
}))
|
||||
|
||||
program.pipe(
|
||||
Effect.provide(NodeHttpClient.layer),
|
||||
NodeRuntime.runMain
|
||||
)
|
||||
Reference in New Issue
Block a user