the-moby-effect
Version:
Moby/Docker API client built using effect-ts
456 lines • 18.8 kB
JavaScript
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Schema from "effect/Schema";
import * as Stream from "effect/Stream";
import * as HttpClient from "effect/unstable/http/HttpClient";
import * as HttpApi from "effect/unstable/httpapi/HttpApi";
import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";
import * as HttpApiEndpoint from "effect/unstable/httpapi/HttpApiEndpoint";
import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
import * as HttpApiSchema from "effect/unstable/httpapi/HttpApiSchema";
import { MobyConnectionOptions } from "../../MobyConnection.js";
import { makeAgnosticHttpClientLayer } from "../../MobyPlatforms.js";
import { ContainerCreateRequest, ImageDeleteResponse, ImageHistoryResponseItem, ImageInspectResponse, ImageSummary, JSONMessage, RegistrySearchResult } from "../generated/index.js";
import { WithRegistryAuthHeader } from "./auth.js";
import { DockerError } from "./circular.js";
import { BadRequest, Conflict, InternalServerError, NotFound } from "./errors.js";
import { BooleanFilter, NumberFilter, StringFilter } from "./filters.js";
/** @since 1.0.0 */
export const ListFilters = /*#__PURE__*/Schema.fromJsonString(/*#__PURE__*/Schema.Struct({
before: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
dangling: /*#__PURE__*/Schema.optional(/*#__PURE__*/BooleanFilter("dangling")),
label: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
reference: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
since: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
until: /*#__PURE__*/Schema.optional(StringFilter)
}));
/** @since 1.0.0 */
export const SearchFilters = /*#__PURE__*/Schema.fromJsonString(/*#__PURE__*/Schema.Struct({
"is-official": /*#__PURE__*/BooleanFilter("is-official").pipe(Schema.optional),
"is-automated": /*#__PURE__*/BooleanFilter("is-automated").pipe(Schema.optional),
stars: /*#__PURE__*/Schema.optional(NumberFilter)
}));
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageList */
const listImagesEndpoint = /*#__PURE__*/HttpApiEndpoint.get("list", "/images/json", {
query: {
filters: /*#__PURE__*/Schema.optional(ListFilters),
all: /*#__PURE__*/Schema.optional(Schema.Boolean),
digests: /*#__PURE__*/Schema.optional(Schema.Boolean),
"shared-size": /*#__PURE__*/Schema.optional(Schema.Boolean)
},
success: /*#__PURE__*/Schema.Array(ImageSummary),
// 200 OK
error: [InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageBuild */
const buildImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("build", "/build", {
query: {
dockerfile: /*#__PURE__*/Schema.optional(Schema.String),
t: /*#__PURE__*/Schema.optional(Schema.String),
extrahosts: /*#__PURE__*/Schema.optional(Schema.String),
remote: /*#__PURE__*/Schema.optional(Schema.String),
q: /*#__PURE__*/Schema.optional(Schema.Boolean),
nocache: /*#__PURE__*/Schema.optional(Schema.Boolean),
cachefrom: /*#__PURE__*/Schema.optional(Schema.String),
pull: /*#__PURE__*/Schema.optional(Schema.String),
rm: /*#__PURE__*/Schema.optional(Schema.Boolean),
forcerm: /*#__PURE__*/Schema.optional(Schema.Boolean),
memory: /*#__PURE__*/Schema.optional(Schema.Number),
memswap: /*#__PURE__*/Schema.optional(Schema.Number),
cpushares: /*#__PURE__*/Schema.optional(Schema.Number),
cpusetcpus: /*#__PURE__*/Schema.optional(Schema.String),
cpuperiod: /*#__PURE__*/Schema.optional(Schema.Number),
cpuquota: /*#__PURE__*/Schema.optional(Schema.Number),
buildargs: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.fromJsonString(/*#__PURE__*/Schema.Record(Schema.String, /*#__PURE__*/Schema.NullishOr(Schema.String)))),
shmsize: /*#__PURE__*/Schema.optional(Schema.Number),
squash: /*#__PURE__*/Schema.optional(Schema.Boolean),
labels: /*#__PURE__*/Schema.optional(Schema.String),
networkmode: /*#__PURE__*/Schema.optional(Schema.String),
platform: /*#__PURE__*/Schema.optional(Schema.String),
target: /*#__PURE__*/Schema.optional(Schema.String),
outputs: /*#__PURE__*/Schema.optional(Schema.String),
version: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Literal("1"))
},
headers: {
"Content-type": /*#__PURE__*/Schema.optional(Schema.String),
"X-Registry-Config": /*#__PURE__*/Schema.optional(Schema.String)
},
payload: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [BadRequest,
// 400 Bad parameter
InternalServerError]
});
/** @since 1.0.0 */
export const BuildPruneFilters = /*#__PURE__*/Schema.fromJsonString(/*#__PURE__*/Schema.Struct({
until: /*#__PURE__*/Schema.optional(StringFilter),
id: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
parent: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
type: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
description: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String)),
inuse: /*#__PURE__*/Schema.optional(/*#__PURE__*/BooleanFilter("inuse")),
shared: /*#__PURE__*/Schema.optional(/*#__PURE__*/BooleanFilter("shared")),
private: /*#__PURE__*/Schema.optional(/*#__PURE__*/BooleanFilter("private"))
}));
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/BuildPrune */
const buildPruneEndpoint = /*#__PURE__*/HttpApiEndpoint.post("buildPrune", "/build/prune", {
query: {
"keep-storage": /*#__PURE__*/Schema.optional(Schema.Number),
all: /*#__PURE__*/Schema.optional(Schema.Boolean),
filters: /*#__PURE__*/Schema.optional(BuildPruneFilters)
},
success: /*#__PURE__*/Schema.Struct({
SpaceReclaimed: /*#__PURE__*/Schema.BigIntFromString.check(/*#__PURE__*/Schema.isBetweenBigInt({
minimum: 0n,
maximum: 2n ** 64n - 1n
})),
CachesDeleted: /*#__PURE__*/Schema.NullishOr(/*#__PURE__*/Schema.Array(Schema.String))
}),
// 200 OK
error: [InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageCreate */
const createImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("create", "/images/create", {
query: {
fromImage: /*#__PURE__*/Schema.optional(Schema.String),
fromSrc: /*#__PURE__*/Schema.optional(Schema.String),
repo: /*#__PURE__*/Schema.optional(Schema.String),
tag: /*#__PURE__*/Schema.optional(Schema.String),
message: /*#__PURE__*/Schema.optional(Schema.String),
changes: /*#__PURE__*/Schema.optional(Schema.String),
platform: /*#__PURE__*/Schema.optional(Schema.String)
},
headers: {
"X-Registry-Auth": /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [NotFound,
// 404 Repository not found or no read access
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageInspect */
const inspectImageEndpoint = /*#__PURE__*/HttpApiEndpoint.get("inspect", "/images/:name/json", {
params: {
name: Schema.String
},
query: {
manifests: /*#__PURE__*/Schema.optional(Schema.Boolean)
},
success: ImageInspectResponse,
// 200 OK
error: [NotFound,
// 404 No such image
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageHistory */
const historyImageEndpoint = /*#__PURE__*/HttpApiEndpoint.get("history", "/images/:name/history", {
params: {
name: Schema.String
},
query: {
platform: /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/Schema.Array(ImageHistoryResponseItem),
// 200 OK
error: [NotFound,
// 404 No such image
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImagePush */
const pushImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("push", "/images/:name/push", {
params: {
name: Schema.String
},
query: {
tag: /*#__PURE__*/Schema.optional(Schema.String),
platform: /*#__PURE__*/Schema.optional(Schema.String)
},
headers: {
"X-Registry-Auth": /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [NotFound,
// 404 No such image
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageTag */
const tagImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("tag", "/images/:name/tag", {
params: {
name: Schema.String
},
query: {
repo: /*#__PURE__*/Schema.optional(Schema.String),
tag: /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/HttpApiSchema.Empty(201),
// 201 Created
error: [BadRequest,
// 400 Bad parameter
NotFound,
// 404 No such image
Conflict,
// 409 Conflict
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageDelete */
const deleteImageEndpoint = /*#__PURE__*/HttpApiEndpoint.delete("delete", "/images/:name", {
params: {
name: Schema.String
},
query: {
force: /*#__PURE__*/Schema.optional(Schema.Boolean),
noprune: /*#__PURE__*/Schema.optional(Schema.Boolean),
platforms: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(Schema.String))
},
success: /*#__PURE__*/Schema.Array(ImageDeleteResponse),
// 200 OK
error: [NotFound,
// 404 No such image
Conflict,
// 409 Conflict
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageSearch */
const searchImagesEndpoint = /*#__PURE__*/HttpApiEndpoint.get("search", "/images/search", {
query: {
term: Schema.String,
limit: /*#__PURE__*/Schema.optional(Schema.Number),
filters: /*#__PURE__*/Schema.optional(SearchFilters)
},
success: /*#__PURE__*/Schema.Array(RegistrySearchResult),
// 200 OK
error: [InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImagePrune */
const pruneImagesEndpoint = /*#__PURE__*/HttpApiEndpoint.post("prune", "/images/prune", {
query: {
filters: /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/Schema.Struct({
SpaceReclaimed: /*#__PURE__*/Schema.BigIntFromString.check(/*#__PURE__*/Schema.isBetweenBigInt({
minimum: 0n,
maximum: 2n ** 64n - 1n
})),
ImagesDeleted: /*#__PURE__*/Schema.NullishOr(/*#__PURE__*/Schema.Array(ImageDeleteResponse))
}),
// 200 OK
error: [InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageCommit */
const commitImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("commit", "/images/commit", {
query: {
container: Schema.String,
repo: /*#__PURE__*/Schema.optional(Schema.String),
tag: /*#__PURE__*/Schema.optional(Schema.String),
comment: /*#__PURE__*/Schema.optional(Schema.String),
author: /*#__PURE__*/Schema.optional(Schema.String),
pause: /*#__PURE__*/Schema.optional(Schema.Boolean),
changes: /*#__PURE__*/Schema.optional(Schema.String)
},
payload: ContainerCreateRequest,
success: /*#__PURE__*/ImageInspectResponse.pipe(/*#__PURE__*/HttpApiSchema.status(201)),
// 201 Created
error: [NotFound,
// 404 No such container
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageGet */
const exportImageEndpoint = /*#__PURE__*/HttpApiEndpoint.get("export", "/images/:name/get", {
params: {
name: Schema.String
},
query: {
platform: /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [NotFound,
// 404 No such image
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageGetAll */
const exportManyImagesEndpoint = /*#__PURE__*/HttpApiEndpoint.get("exportMany", "/images/get", {
query: {
names: /*#__PURE__*/Schema.optional(Schema.String),
platform: /*#__PURE__*/Schema.optional(Schema.String)
},
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [NotFound,
// 404 No such image
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image/operation/ImageLoad */
const importImageEndpoint = /*#__PURE__*/HttpApiEndpoint.post("import", "/images/load", {
query: {
platform: /*#__PURE__*/Schema.optional(Schema.String),
quiet: /*#__PURE__*/Schema.optional(Schema.Boolean)
},
payload: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
success: /*#__PURE__*/HttpApiSchema.StreamUint8Array(),
// 200 OK (streaming response)
error: [BadRequest,
// 400 Bad parameter
InternalServerError]
});
/** @see https://docs.docker.com/reference/api/engine/latest/#tag/Image */
const ImagesGroup = /*#__PURE__*/HttpApiGroup.make("images").add(listImagesEndpoint, buildImageEndpoint, buildPruneEndpoint, createImageEndpoint, inspectImageEndpoint, historyImageEndpoint, pushImageEndpoint, tagImageEndpoint, deleteImageEndpoint, searchImagesEndpoint, pruneImagesEndpoint, commitImageEndpoint, exportImageEndpoint, exportManyImagesEndpoint, importImageEndpoint);
/**
* @since 1.0.0
* @category HttpApi
* @see https://docs.docker.com/reference/api/engine/latest/#tag/Image
*/
export const ImagesApi = /*#__PURE__*/HttpApi.make("ImagesApi").add(ImagesGroup);
/**
* @since 1.0.0
* @category Services
* @see https://docs.docker.com/reference/api/engine/latest/#tag/Image
*/
export class Images extends /*#__PURE__*/Context.Service()("@the-moby-effect/endpoints/Images", {
make: /*#__PURE__*/Effect.gen(function* () {
const httpClient = yield* Effect.map(HttpClient.HttpClient, WithRegistryAuthHeader(buildImageEndpoint, createImageEndpoint, pushImageEndpoint));
const ImagesError = DockerError.WrapForModule("images");
const client = yield* HttpApiClient.group(ImagesApi, {
group: "images",
httpClient
});
const decodeJsonMessage = Schema.decodeEffect(Schema.fromJsonString(JSONMessage));
const list_ = options => client.list({
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("list")));
const build_ = (build, options) => Effect.contextWith(context => client.build({
query: {
...options
},
headers: {
"Content-type": "application/tar"
},
payload: Stream.provideContext(build, context)
})).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("build")));
const buildPrune_ = options => client.buildPrune({
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("buildPrune")));
const create_ = options => client.create({
headers: {},
query: {
...options
}
}).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("create")));
const inspect_ = (name, options) => client.inspect({
params: {
name
},
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("inspect")));
const history_ = (name, options) => client.history({
params: {
name
},
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("history")));
const push_ = (name, options) => client.push({
params: {
name
},
query: {
...options
},
headers: {}
}).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("push")));
const tag_ = (name, options) => client.tag({
params: {
name
},
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("tag")));
const delete_ = (name, options) => client.delete({
params: {
name
},
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("delete")));
const search_ = options => client.search({
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("search")));
const prune_ = options => client.prune({
query: {
...options
}
}).pipe(Effect.mapError(ImagesError("prune")));
const commit_ = (payload, options) => ContainerCreateRequest.makeEffect(payload).pipe(Effect.flatMap(payload => client.commit({
query: {
...options
},
payload
})), Effect.mapError(ImagesError("commit")));
const export_ = (name, options) => client.export({
params: {
name
},
query: {
...options
}
}).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("export")));
const exportMany_ = options => client.exportMany({
query: {
...options
}
}).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("exportMany")));
const import_ = (build, options) => Effect.contextWith(context => client.import({
query: {
...options
},
payload: Stream.provideContext(build, context)
})).pipe(Stream.unwrap, Stream.decodeText(), Stream.splitLines, Stream.mapEffect(line => decodeJsonMessage(line)), Stream.mapError(ImagesError("import")));
return {
list: list_,
build: build_,
buildPrune: buildPrune_,
create: create_,
inspect: inspect_,
history: history_,
push: push_,
tag: tag_,
delete: delete_,
search: search_,
prune: prune_,
commit: commit_,
export: export_,
exportMany: exportMany_,
import: import_
};
})
}) {}
/**
* @since 1.0.0
* @category Services
* @see https://docs.docker.com/reference/api/engine/latest/#tag/Image
*/
export const ImagesLayer = /*#__PURE__*/Layer.effect(Images, Images.make);
/**
* @since 1.0.0
* @category Services
* @see https://docs.docker.com/reference/api/engine/latest/#tag/Image
*/
export const ImagesLayerLocalSocket = /*#__PURE__*/ImagesLayer.pipe(/*#__PURE__*/Layer.provide(/*#__PURE__*/makeAgnosticHttpClientLayer(/*#__PURE__*/MobyConnectionOptions.socket({
socketPath: "/var/run/docker.sock"
}))));
//# sourceMappingURL=images.js.map