@@ -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