the-moby-effect
Version:
Moby/Docker API client built using effect-ts
478 lines (437 loc) • 13.6 kB
text/typescript
/**
* Docker engine.
*
* @since 1.0.0
*/
import type * as Effect from "effect/Effect";
import type * as Schema from "effect/Schema";
import type * as Scope from "effect/Scope";
import type * as Stream from "effect/Stream";
import type * as HttpClient from "effect/unstable/http/HttpClient";
import type * as Socket from "effect/unstable/socket/Socket";
import * as Function from "effect/Function";
import * as Layer from "effect/Layer";
import type * as IdSchemas from "./internal/schemas/id.ts";
import type * as MobyConnection from "./MobyConnection.ts";
import type * as MobyDemux from "./MobyDemux.ts";
import type * as MobySchemas from "./MobySchemas.ts";
import * as internalCircular from "./internal/endpoints/circular.ts";
import * as internalDocker from "./internal/engines/docker.ts";
import * as MobyEndpoints from "./MobyEndpoints.ts";
import * as MobyPlatforms from "./MobyPlatforms.ts";
/**
* @since 1.0.0
* @category Errors
*/
export const DockerErrorTypeId: unique symbol = internalCircular.DockerErrorTypeId;
/**
* @since 1.0.0
* @category Errors
*/
export type DockerErrorTypeId = typeof DockerErrorTypeId;
/**
* @since 1.0.0
* @category Errors
*/
export const isDockerError: (u: unknown) => u is DockerError = internalCircular.isDockerError;
/**
* @since 1.0.0
* @category Errors
*/
export type DockerError = internalCircular.DockerError;
/**
* @since 1.0.0
* @category Errors
*/
export const DockerError: typeof internalCircular.DockerError = internalCircular.DockerError;
/**
* @since 1.0.0
* @category Layers
*/
export type DockerLayer = Layer.Layer<
| MobyEndpoints.Configs
| MobyEndpoints.Containers
| MobyEndpoints.Distributions
| MobyEndpoints.Execs
| MobyEndpoints.Images
| MobyEndpoints.Networks
| MobyEndpoints.Nodes
| MobyEndpoints.Plugins
| MobyEndpoints.Secrets
| MobyEndpoints.Services
| MobyEndpoints.Sessions
| MobyEndpoints.Swarm
| MobyEndpoints.System
| MobyEndpoints.Tasks
| MobyEndpoints.Volumes,
never,
never
>;
/**
* @since 1.0.0
* @category Layers
*/
export type DockerLayerWithoutHttpClientOrWebsocketConstructor = Layer.Layer<
Layer.Success<DockerLayer>,
Layer.Error<DockerLayer>,
Layer.Services<DockerLayer> | HttpClient.HttpClient | Socket.WebSocketConstructor
>;
/**
* @since 1.0.0
* @category Layers
*/
export const layerWithoutHttpCLient: DockerLayerWithoutHttpClientOrWebsocketConstructor = Layer.mergeAll(
MobyEndpoints.ConfigsLayer,
MobyEndpoints.ContainersLayer,
MobyEndpoints.DistributionsLayer,
MobyEndpoints.ExecsLayer,
MobyEndpoints.ImagesLayer,
MobyEndpoints.NetworksLayer,
MobyEndpoints.NodesLayer,
MobyEndpoints.PluginsLayer,
MobyEndpoints.SecretsLayer,
MobyEndpoints.ServicesLayer,
MobyEndpoints.SessionsLayer,
MobyEndpoints.SwarmLayer,
MobyEndpoints.SystemLayer,
MobyEndpoints.TasksLayer,
MobyEndpoints.VolumesLayer
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerNodeJS: (connectionOptions: MobyConnection.MobyConnectionOptions) => DockerLayer = Function.compose(
MobyPlatforms.makeNodeHttpClientLayer,
(httpClientLayer) => Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerBun: (connectionOptions: MobyConnection.MobyConnectionOptions) => DockerLayer = Function.compose(
MobyPlatforms.makeBunHttpClientLayer,
(httpClientLayer) => Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerDeno: (connectionOptions: MobyConnection.MobyConnectionOptions) => DockerLayer = Function.compose(
MobyPlatforms.makeDenoHttpClientLayer,
(httpClientLayer) => Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerUndici: (connectionOptions: MobyConnection.MobyConnectionOptions) => DockerLayer = Function.compose(
MobyPlatforms.makeUndiciHttpClientLayer,
(httpClientLayer) => Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerWeb: (
connectionOptions: MobyConnection.HttpConnectionOptionsTagged | MobyConnection.HttpsConnectionOptionsTagged
) => DockerLayer = Function.compose(MobyPlatforms.makeWebHttpClientLayer, (httpClientLayer) =>
Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerFetch: (
connectionOptions: MobyConnection.HttpConnectionOptionsTagged | MobyConnection.HttpsConnectionOptionsTagged
) => DockerLayer = Function.compose(MobyPlatforms.makeFetchHttpClientLayer, (httpClientLayer) =>
Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
/**
* @since 1.0.0
* @category Layers
*/
export const layerAgnostic: (
connectionOptions: MobyConnection.HttpConnectionOptionsTagged | MobyConnection.HttpsConnectionOptionsTagged
) => DockerLayerWithoutHttpClientOrWebsocketConstructor = Function.compose(
MobyPlatforms.makeAgnosticHttpClientLayer,
(httpClientLayer) => Layer.provide(layerWithoutHttpCLient, httpClientLayer)
);
export {
/**
* @since 1.0.0
* @category Auth
* @see https://docs.docker.com/reference/api/engine/version/v1.51/#section/Authentication
*/
RegistryAuth,
} from "./internal/endpoints/auth.ts";
/**
* Implements the `docker build` command. It doesn't have all the flags that the
* images build endpoint exposes.
*
* @since 1.0.0
* @category Docker
*/
export const build: <E1>({
buildargs,
context,
dockerfile,
platform,
tag,
}: {
tag: string;
platform?: string | undefined;
dockerfile?: string | undefined;
context: Stream.Stream<Uint8Array, E1, never>;
buildargs?: Record<string, string | undefined> | undefined;
}) => Stream.Stream<MobySchemas.JSONMessage, DockerError, MobyEndpoints.Images> = internalDocker.build;
/**
* Implements the `docker build` command as a scoped effect. When the scope is
* closed, the built image is removed. It doesn't have all the flags that the
* images build endpoint exposes.
*
* @since 1.0.0
* @category Docker
*/
export const buildScoped: <E1>({
buildargs,
context,
dockerfile,
platform,
tag,
}: {
tag: string;
platform?: string | undefined;
dockerfile?: string | undefined;
buildargs?: Record<string, string | undefined> | undefined;
context: Stream.Stream<Uint8Array, E1, never>;
}) => Effect.Effect<
Stream.Stream<MobySchemas.JSONMessage, DockerError, never>,
never,
Scope.Scope | MobyEndpoints.Images
> = internalDocker.buildScoped;
/**
* Implements the `docker exec` command in a blocking fashion. Incompatible with
* web.
*
* @since 1.0.0
* @category Docker
*/
export const exec: ({
command,
containerId,
}: {
command: string | Array<string>;
containerId: IdSchemas.ContainerIdentifier;
}) => Effect.Effect<
[exitCode: bigint, output: string],
Socket.SocketError | Schema.SchemaError | DockerError,
MobyEndpoints.Execs
> = internalDocker.exec;
/**
* Implements the `docker exec` command in a non blocking fashion. Incompatible
* with web when not detached.
*
* @since 1.0.0
* @category Docker
*/
export const execNonBlocking: <const T extends boolean = false>({
command,
containerId,
detach,
}: {
detach: T;
command: string | Array<string>;
containerId: IdSchemas.ContainerIdentifier;
}) => Effect.Effect<
[[T] extends [false] ? MobyDemux.RawSocket | MobyDemux.MultiplexedSocket : void, IdSchemas.ExecIdentifier],
Socket.SocketError | Schema.SchemaError | DockerError,
MobyEndpoints.Execs
> = internalDocker.execNonBlocking;
/**
* Implements the `docker exec` command in a blocking fashion with websockets as
* the underlying transport instead of the docker engine exec apis so that is
* can be compatible with web.
*
* @since 1.0.0
* @category Docker
*/
export const execWebsockets: ({
command,
containerId,
}: {
command: string | Array<string>;
containerId: IdSchemas.ContainerIdentifier;
}) => Effect.Effect<
readonly [stdout: string, stderr: string],
Socket.SocketError | Schema.SchemaError | DockerError,
MobyEndpoints.Containers
> = internalDocker.execWebsockets;
/**
* Implements the `docker exec` command in a non blocking fashion with
* websockets as the underlying transport instead of the docker engine exec apis
* so that is can be compatible with web.
*
* @since 1.0.0
* @category Docker
*/
export const execWebsocketsNonBlocking: ({
command,
containerId,
cwd,
}: {
command: string | Array<string>;
containerId: IdSchemas.ContainerIdentifier;
cwd?: string | undefined;
}) => Effect.Effect<
MobyDemux.MultiplexedChannel<never, Socket.SocketError | DockerError, never>,
never,
MobyEndpoints.Containers
> = internalDocker.execWebsocketsNonBlocking;
/**
* Implements the `docker images` command.
*
* @since 1.0.0
* @category Docker
*/
export const images: (
options?: Parameters<MobyEndpoints.Images["Service"]["list"]>[0]
) => Effect.Effect<ReadonlyArray<MobySchemas.ImageSummary>, DockerError, MobyEndpoints.Images> = internalDocker.images;
/**
* Implements the `docker info` command.
*
* @since 1.0.0
* @category Docker
*/
export const info: () => Effect.Effect<MobySchemas.SystemInfo, DockerError, MobyEndpoints.System> = internalDocker.info;
/**
* Implements the `docker ping` command.
*
* @since 1.0.0
* @category Docker
*/
export const ping: () => Effect.Effect<void, DockerError, MobyEndpoints.System> = internalDocker.ping;
/**
* Implements the `docker ping` command.
*
* @since 1.0.0
* @category Docker
*/
export const pingHead: () => Effect.Effect<void, DockerError, MobyEndpoints.System> = internalDocker.pingHead;
/**
* Implements the `docker ps` command.
*
* @since 1.0.0
* @category Docker
*/
export const ps: (
options?: Parameters<MobyEndpoints.Containers["Service"]["list"]>[0]
) => Effect.Effect<ReadonlyArray<MobySchemas.ContainerSummary>, DockerError, MobyEndpoints.Containers> =
internalDocker.ps;
/**
* Implements the `docker pull` command. It does not have all the flags that the
* images create endpoint exposes.
*
* @since 1.0.0
* @category Docker
*/
export const pull: ({
image,
platform,
}: {
image: string;
platform?: string | undefined;
}) => Stream.Stream<MobySchemas.JSONMessage, DockerError, MobyEndpoints.Images> = internalDocker.pull;
/**
* Implements the `docker pull` command as a scoped effect. When the scope is
* closed, the pulled image is removed. It doesn't have all the flag =
* internalDocker.flags that the images create endpoint exposes.
*
* @since 1.0.0
* @category Docker
*/
export const pullScoped: ({
image,
platform,
}: {
image: string;
platform?: string | undefined;
}) => Effect.Effect<
Stream.Stream<MobySchemas.JSONMessage, DockerError, never>,
never,
MobyEndpoints.Images | Scope.Scope
> = internalDocker.pullScoped;
/**
* Implements the `docker push` command.
*
* @since 1.0.0
* @category Docker
*/
export const push: (
name: string,
options: Parameters<MobyEndpoints.Images["Service"]["push"]>[1]
) => Stream.Stream<MobySchemas.JSONMessage, DockerError, MobyEndpoints.Images> = internalDocker.push;
/**
* Implements `docker run` command.
*
* @since 1.0.0
* @category Docker
*/
export const run: (
options: Omit<(typeof MobySchemas.ContainerCreateRequest)["~type.make.in"], "HostConfig"> & {
readonly name?: string | undefined;
readonly platform?: string | undefined;
readonly HostConfig?: (typeof MobySchemas.ContainerHostConfig)["~type.make.in"] | undefined;
}
) => Effect.Effect<MobySchemas.ContainerInspectResponse, DockerError, MobyEndpoints.Containers> = internalDocker.run;
/**
* Implements `docker run` command as a scoped effect. When the scope is closed,
* both the image and the container is removed = internalDocker.removed.
*
* @since 1.0.0
* @category Docker
*/
export const runScoped: (
options: Omit<(typeof MobySchemas.ContainerCreateRequest)["~type.make.in"], "HostConfig"> & {
readonly name?: string | undefined;
readonly platform?: string | undefined;
readonly HostConfig?: (typeof MobySchemas.ContainerHostConfig)["~type.make.in"] | undefined;
}
) => Effect.Effect<MobySchemas.ContainerInspectResponse, DockerError, Scope.Scope | MobyEndpoints.Containers> =
internalDocker.runScoped;
/**
* Implements the `docker search` command.
*
* @since 1.0.0
* @category Docker
*/
export const search: (
options: Parameters<MobyEndpoints.Images["Service"]["search"]>[0]
) => Effect.Effect<ReadonlyArray<MobySchemas.RegistrySearchResult>, DockerError, MobyEndpoints.Images> =
internalDocker.search;
/**
* Implements the `docker start` command.
*
* @since 1.0.0
* @category Docker
*/
export const start: (
containerId: IdSchemas.ContainerIdentifier
) => Effect.Effect<void, DockerError, MobyEndpoints.Containers> = internalDocker.start;
/**
* Implements the `docker stop` command.
*
* @since 1.0.0
* @category Docker
*/
export const stop: (
containerId: IdSchemas.ContainerIdentifier
) => Effect.Effect<void, DockerError, MobyEndpoints.Containers> = internalDocker.stop;
/**
* Implements the `docker version` command.
*
* @since 1.0.0
* @category Docker
*/
export const version: () => Effect.Effect<MobySchemas.TypesVersion, DockerError, MobyEndpoints.System> =
internalDocker.version;