@distilled.cloud/docker 0.0.0 → 1.0.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/lib/credentials.d.ts +34 -0
- package/lib/credentials.d.ts.map +1 -0
- package/lib/credentials.js +33 -0
- package/lib/credentials.js.map +1 -0
- package/lib/errors.d.ts +36 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +26 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +28 -0
- package/lib/index.js.map +1 -0
- package/lib/pagination.d.ts +8 -0
- package/lib/pagination.d.ts.map +1 -0
- package/lib/pagination.js +8 -0
- package/lib/pagination.js.map +1 -0
- package/lib/protocol.d.ts +18 -0
- package/lib/protocol.d.ts.map +1 -0
- package/lib/protocol.js +48 -0
- package/lib/protocol.js.map +1 -0
- package/lib/retry.d.ts +32 -0
- package/lib/retry.d.ts.map +1 -0
- package/lib/retry.js +32 -0
- package/lib/retry.js.map +1 -0
- package/lib/services/docker.d.ts +5723 -0
- package/lib/services/docker.d.ts.map +1 -0
- package/lib/services/docker.js +4194 -0
- package/lib/services/docker.js.map +1 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +3 -0
- package/lib/services/index.js.map +1 -0
- package/lib/traits.d.ts +11 -0
- package/lib/traits.d.ts.map +1 -0
- package/lib/traits.js +11 -0
- package/lib/traits.js.map +1 -0
- package/package.json +77 -6
- package/src/credentials.ts +54 -0
- package/src/errors.ts +50 -0
- package/src/index.ts +42 -0
- package/src/pagination.ts +7 -0
- package/src/protocol.ts +71 -0
- package/src/retry.ts +54 -0
- package/src/services/docker.ts +11957 -0
- package/src/services/index.ts +2 -0
- package/src/traits.ts +44 -0
package/package.json
CHANGED
|
@@ -1,14 +1,85 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@distilled.cloud/docker",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Placeholder package for an upcoming distilled SDK.",
|
|
5
|
-
"license": "Apache-2.0",
|
|
3
|
+
"version": "1.0.0-rc.11",
|
|
6
4
|
"repository": {
|
|
7
5
|
"type": "git",
|
|
8
6
|
"url": "https://github.com/alchemy-run/distilled",
|
|
9
7
|
"directory": "packages/docker"
|
|
10
8
|
},
|
|
11
|
-
"
|
|
12
|
-
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"files": [
|
|
13
|
+
"lib",
|
|
14
|
+
"src"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/index.d.ts",
|
|
19
|
+
"bun": "./src/index.ts",
|
|
20
|
+
"worker": "./src/index.ts",
|
|
21
|
+
"default": "./lib/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./Credentials": {
|
|
24
|
+
"types": "./lib/credentials.d.ts",
|
|
25
|
+
"bun": "./src/credentials.ts",
|
|
26
|
+
"worker": "./src/credentials.ts",
|
|
27
|
+
"default": "./lib/credentials.js"
|
|
28
|
+
},
|
|
29
|
+
"./Errors": {
|
|
30
|
+
"types": "./lib/errors.d.ts",
|
|
31
|
+
"bun": "./src/errors.ts",
|
|
32
|
+
"worker": "./src/errors.ts",
|
|
33
|
+
"default": "./lib/errors.js"
|
|
34
|
+
},
|
|
35
|
+
"./Traits": {
|
|
36
|
+
"types": "./lib/traits.d.ts",
|
|
37
|
+
"bun": "./src/traits.ts",
|
|
38
|
+
"worker": "./src/traits.ts",
|
|
39
|
+
"default": "./lib/traits.js"
|
|
40
|
+
},
|
|
41
|
+
"./Pagination": {
|
|
42
|
+
"types": "./lib/pagination.d.ts",
|
|
43
|
+
"bun": "./src/pagination.ts",
|
|
44
|
+
"worker": "./src/pagination.ts",
|
|
45
|
+
"default": "./lib/pagination.js"
|
|
46
|
+
},
|
|
47
|
+
"./Protocol": {
|
|
48
|
+
"types": "./lib/protocol.d.ts",
|
|
49
|
+
"bun": "./src/protocol.ts",
|
|
50
|
+
"worker": "./src/protocol.ts",
|
|
51
|
+
"default": "./lib/protocol.js"
|
|
52
|
+
},
|
|
53
|
+
"./Retry": {
|
|
54
|
+
"types": "./lib/retry.d.ts",
|
|
55
|
+
"bun": "./src/retry.ts",
|
|
56
|
+
"worker": "./src/retry.ts",
|
|
57
|
+
"default": "./lib/retry.js"
|
|
58
|
+
},
|
|
59
|
+
"./*": {
|
|
60
|
+
"types": "./lib/services/*.d.ts",
|
|
61
|
+
"bun": "./src/services/*.ts",
|
|
62
|
+
"worker": "./src/services/*.ts",
|
|
63
|
+
"default": "./lib/services/*.js"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@distilled.cloud/core": "1.0.0-rc.11"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/bun": "1.3.14",
|
|
71
|
+
"@types/node": "26.2.0",
|
|
72
|
+
"@effect/platform-bun": ">=4.0.0-rc.115 || >=4.0.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"effect": ">=4.0.0-rc.115 || >=4.0.0"
|
|
76
|
+
},
|
|
77
|
+
"scripts": {
|
|
78
|
+
"build": "tsc -b",
|
|
79
|
+
"convert": "bun scripts/convert.ts",
|
|
80
|
+
"generate": "bun scripts/convert.ts && bun scripts/generate.ts",
|
|
81
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
82
|
+
"specs:fetch": "git submodule update --force --init --depth=1 specs/spec-mirror-docker",
|
|
83
|
+
"specs:update": "git submodule update --remote --force --depth=1 specs/spec-mirror-docker"
|
|
13
84
|
}
|
|
14
|
-
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker credentials — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* The `Credentials` service holds an *effect* that resolves the current
|
|
5
|
+
* credentials on every request (the protocol layer resolves it per request
|
|
6
|
+
* on the calling fiber). The Engine API is typically unauthenticated over a
|
|
7
|
+
* local socket or TCP port; an optional bearer token covers TLS-proxied
|
|
8
|
+
* remotes. Registry auth is a per-call `X-Registry-Auth` header, not a
|
|
9
|
+
* credential here.
|
|
10
|
+
*/
|
|
11
|
+
import * as Context from "effect/Context";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import * as Redacted from "effect/Redacted";
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_API_BASE_URL = "http://localhost/v1.56";
|
|
17
|
+
|
|
18
|
+
export interface Config {
|
|
19
|
+
readonly apiKey?: Redacted.Redacted<string>;
|
|
20
|
+
readonly apiBaseUrl: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class Credentials extends Context.Service<
|
|
24
|
+
Credentials,
|
|
25
|
+
Effect.Effect<Config>
|
|
26
|
+
>()("DockerCredentials") {}
|
|
27
|
+
|
|
28
|
+
/** Layer from an optional API key + optional base URL. */
|
|
29
|
+
export const fromApiKey = (config: {
|
|
30
|
+
readonly apiKey?: string;
|
|
31
|
+
readonly apiBaseUrl?: string;
|
|
32
|
+
}): Layer.Layer<Credentials> =>
|
|
33
|
+
Layer.succeed(
|
|
34
|
+
Credentials,
|
|
35
|
+
Effect.succeed({
|
|
36
|
+
apiKey:
|
|
37
|
+
config.apiKey !== undefined ? Redacted.make(config.apiKey) : undefined,
|
|
38
|
+
apiBaseUrl: config.apiBaseUrl ?? DEFAULT_API_BASE_URL,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Reads DOCKER_API_KEY (optional) and DOCKER_API_BASE_URL (optional).
|
|
44
|
+
* Defaults to {@link DEFAULT_API_BASE_URL} with no Authorization header.
|
|
45
|
+
*/
|
|
46
|
+
export const CredentialsFromEnv: Layer.Layer<Credentials> = Layer.succeed(
|
|
47
|
+
Credentials,
|
|
48
|
+
Effect.succeed({
|
|
49
|
+
apiKey: process.env.DOCKER_API_KEY
|
|
50
|
+
? Redacted.make(process.env.DOCKER_API_KEY)
|
|
51
|
+
: undefined,
|
|
52
|
+
apiBaseUrl: process.env.DOCKER_API_BASE_URL ?? DEFAULT_API_BASE_URL,
|
|
53
|
+
}),
|
|
54
|
+
);
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker-specific error types.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the common HTTP errors from core and adds the Docker fallback
|
|
5
|
+
* errors. Note the generated service module additionally defines its own
|
|
6
|
+
* per-status matcher classes (BadRequest/NotFound/…) for the statuses each
|
|
7
|
+
* operation declares — those share `_tag`s with the core classes here, so
|
|
8
|
+
* `catchTag` works against either.
|
|
9
|
+
*/
|
|
10
|
+
export {
|
|
11
|
+
BadGateway,
|
|
12
|
+
BadRequest,
|
|
13
|
+
Conflict,
|
|
14
|
+
ConfigError,
|
|
15
|
+
Forbidden,
|
|
16
|
+
GatewayTimeout,
|
|
17
|
+
InternalServerError,
|
|
18
|
+
Locked,
|
|
19
|
+
NotFound,
|
|
20
|
+
ServiceUnavailable,
|
|
21
|
+
TooManyRequests,
|
|
22
|
+
Unauthorized,
|
|
23
|
+
UnprocessableEntity,
|
|
24
|
+
HTTP_STATUS_MAP,
|
|
25
|
+
DEFAULT_ERRORS,
|
|
26
|
+
API_ERRORS,
|
|
27
|
+
} from "@distilled.cloud/core/errors";
|
|
28
|
+
export type { DefaultErrors } from "@distilled.cloud/core/errors";
|
|
29
|
+
|
|
30
|
+
import * as Schema from "effect/Schema";
|
|
31
|
+
import * as Category from "@distilled.cloud/core/category";
|
|
32
|
+
|
|
33
|
+
/** Unknown Docker error — returned when nothing else matches the failure. */
|
|
34
|
+
export class UnknownDockerError extends Schema.TaggedError<UnknownDockerError>()(
|
|
35
|
+
"UnknownDockerError",
|
|
36
|
+
{
|
|
37
|
+
code: Schema.optional(Schema.String),
|
|
38
|
+
message: Schema.optional(Schema.String),
|
|
39
|
+
body: Schema.Unknown,
|
|
40
|
+
},
|
|
41
|
+
).pipe(Category.withServerError) {}
|
|
42
|
+
|
|
43
|
+
/** Schema parse error wrapper. */
|
|
44
|
+
export class DockerParseError extends Schema.TaggedError<DockerParseError>()(
|
|
45
|
+
"DockerParseError",
|
|
46
|
+
{
|
|
47
|
+
body: Schema.Unknown,
|
|
48
|
+
cause: Schema.Unknown,
|
|
49
|
+
},
|
|
50
|
+
).pipe(Category.withParseError) {}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @distilled.cloud/docker — Docker Engine SDK for Effect.
|
|
3
|
+
*
|
|
4
|
+
* `./services` is generated by `scripts/generate.ts` from the Smithy model
|
|
5
|
+
* in `.generated-specs` (written by `scripts/convert.ts` from the OpenAPI
|
|
6
|
+
* spec). Everything else in this folder is hand-written.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import * as Docker from "@distilled.cloud/docker";
|
|
11
|
+
*
|
|
12
|
+
* const containers = yield* Docker.Services.docker.containerList({});
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export {
|
|
16
|
+
Credentials,
|
|
17
|
+
CredentialsFromEnv,
|
|
18
|
+
DEFAULT_API_BASE_URL,
|
|
19
|
+
fromApiKey,
|
|
20
|
+
} from "./credentials.ts";
|
|
21
|
+
export type { Config as DockerClientConfig } from "./credentials.ts";
|
|
22
|
+
export * from "./errors.ts";
|
|
23
|
+
export * as T from "./traits.ts";
|
|
24
|
+
export {
|
|
25
|
+
DockerProtocol,
|
|
26
|
+
type DockerOpError,
|
|
27
|
+
type DockerOpContext,
|
|
28
|
+
} from "./protocol.ts";
|
|
29
|
+
export { paginateCursor } from "./pagination.ts";
|
|
30
|
+
export * as Retry from "./retry.ts";
|
|
31
|
+
export * as Services from "./services/index.ts";
|
|
32
|
+
// Operations (and their request/response types) are importable straight off
|
|
33
|
+
// the package root. The service-local typed error classes shadow the
|
|
34
|
+
// same-named shared ones from ./errors.ts — the ops actually raise the
|
|
35
|
+
// service-local classes.
|
|
36
|
+
export * from "./services/docker.ts";
|
|
37
|
+
export {
|
|
38
|
+
BadRequest,
|
|
39
|
+
Conflict,
|
|
40
|
+
Forbidden,
|
|
41
|
+
NotFound,
|
|
42
|
+
} from "./services/docker.ts";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker pagination — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* Generated operations that carry a cursor-mode `smithy.api#paginated`
|
|
5
|
+
* trait pass core's {@link paginateCursor} strategy to `API.makePaginated`.
|
|
6
|
+
*/
|
|
7
|
+
export { paginateCursor } from "@distilled.cloud/core/pagination";
|
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DockerProtocol — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* Docker Engine speaks plain JSON REST (no response envelope), so the whole
|
|
5
|
+
* protocol is one `makeRestProtocol` call from `core/protocol-rest`:
|
|
6
|
+
*
|
|
7
|
+
* request: credentials → optional `Authorization: Bearer <apiKey>` +
|
|
8
|
+
* base URL (default http://localhost/v1.56), resolved from the
|
|
9
|
+
* calling fiber on every request
|
|
10
|
+
*
|
|
11
|
+
* response: 2xx JSON is the payload (sensitive members delivered as
|
|
12
|
+
* `Redacted`); non-2xx `{ message }` bodies map to the
|
|
13
|
+
* operation's typed error classes by status, then the shared
|
|
14
|
+
* HTTP-status classes, then {@link UnknownDockerError}.
|
|
15
|
+
*/
|
|
16
|
+
import * as Effect from "effect/Effect";
|
|
17
|
+
import type * as Layer from "effect/Layer";
|
|
18
|
+
import * as Redacted from "effect/Redacted";
|
|
19
|
+
import type * as HttpClient from "effect/unstable/http/HttpClient";
|
|
20
|
+
import type * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
21
|
+
import type * as API from "@distilled.cloud/core/api";
|
|
22
|
+
import { makeRestProtocol } from "@distilled.cloud/core/protocol-rest";
|
|
23
|
+
import type { API_ERRORS, ConfigError } from "@distilled.cloud/core/errors";
|
|
24
|
+
import { Credentials, type Config } from "./credentials.ts";
|
|
25
|
+
import { UnknownDockerError } from "./errors.ts";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Error channel shared by every generated Docker operation. Generated service
|
|
29
|
+
* files annotate operations with `API.OperationMethod<I, O, DockerOpError,
|
|
30
|
+
* DockerOpContext>` explicitly so the compiler never infers these back out of
|
|
31
|
+
* the schema generics.
|
|
32
|
+
*/
|
|
33
|
+
export type DockerOpError =
|
|
34
|
+
| InstanceType<(typeof API_ERRORS)[number]>
|
|
35
|
+
| UnknownDockerError
|
|
36
|
+
| ConfigError
|
|
37
|
+
| HttpClientError.HttpClientError;
|
|
38
|
+
|
|
39
|
+
/** Context (requirements) shared by every generated Docker operation. */
|
|
40
|
+
export type DockerOpContext = Credentials | HttpClient.HttpClient;
|
|
41
|
+
|
|
42
|
+
export const DockerProtocol: Layer.Layer<API.Protocol> =
|
|
43
|
+
makeRestProtocol<Config>({
|
|
44
|
+
// The Credentials service holds an effect — resolving it here (per
|
|
45
|
+
// request, on the calling fiber) picks up context-provided credentials.
|
|
46
|
+
credentials: Effect.gen(function* () {
|
|
47
|
+
const resolve = yield* Credentials;
|
|
48
|
+
return yield* resolve;
|
|
49
|
+
}),
|
|
50
|
+
baseUrl: (creds) => creds.apiBaseUrl,
|
|
51
|
+
headers: (creds): Record<string, string> => {
|
|
52
|
+
const headers: Record<string, string> = {};
|
|
53
|
+
if (creds.apiKey !== undefined) {
|
|
54
|
+
headers.Authorization = `Bearer ${Redacted.value(creds.apiKey)}`;
|
|
55
|
+
}
|
|
56
|
+
return headers;
|
|
57
|
+
},
|
|
58
|
+
// Docker's error body is `{ message: string }` — the factory's default
|
|
59
|
+
// lenient envelope covers it.
|
|
60
|
+
unknownError: ({ code, message, body }) =>
|
|
61
|
+
new UnknownDockerError({
|
|
62
|
+
code:
|
|
63
|
+
typeof code === "string"
|
|
64
|
+
? code
|
|
65
|
+
: code !== undefined
|
|
66
|
+
? String(code)
|
|
67
|
+
: undefined,
|
|
68
|
+
message,
|
|
69
|
+
body,
|
|
70
|
+
}),
|
|
71
|
+
});
|
package/src/retry.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker retry configuration.
|
|
3
|
+
*
|
|
4
|
+
* Defines the per-SDK `Retry` Context.Service tag that generated operations
|
|
5
|
+
* wire into `API.make`. Callers can install a blanket retry policy at the
|
|
6
|
+
* layer level and have every Docker API call below it pick it up:
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import * as Docker from "@distilled.cloud/docker";
|
|
11
|
+
*
|
|
12
|
+
* myEffect.pipe(Docker.Retry.transient);
|
|
13
|
+
* Effect.provide(myEffect, Layer.succeed(Docker.Retry.Retry, customPolicy));
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
import * as Context from "effect/Context";
|
|
17
|
+
import * as Effect from "effect/Effect";
|
|
18
|
+
import * as Layer from "effect/Layer";
|
|
19
|
+
import {
|
|
20
|
+
type Policy,
|
|
21
|
+
throttlingFactory,
|
|
22
|
+
transientFactory,
|
|
23
|
+
} from "@distilled.cloud/core/retry";
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
type Options,
|
|
27
|
+
type Factory,
|
|
28
|
+
type Policy,
|
|
29
|
+
makeDefault,
|
|
30
|
+
jittered,
|
|
31
|
+
capped,
|
|
32
|
+
throttlingOptions,
|
|
33
|
+
transientOptions,
|
|
34
|
+
throttlingFactory,
|
|
35
|
+
transientFactory,
|
|
36
|
+
} from "@distilled.cloud/core/retry";
|
|
37
|
+
|
|
38
|
+
/** Context tag for configuring retry behavior of Docker API calls. */
|
|
39
|
+
export class Retry extends Context.Service<Retry, Policy>()("DockerRetry") {}
|
|
40
|
+
|
|
41
|
+
/** Provides a custom retry policy to every Docker API call below it. */
|
|
42
|
+
export const policy = (optionsOrFactory: Policy) =>
|
|
43
|
+
Effect.provide(Layer.succeed(Retry, optionsOrFactory));
|
|
44
|
+
|
|
45
|
+
/** Disables all automatic retries. */
|
|
46
|
+
export const none = Effect.provide(
|
|
47
|
+
Layer.succeed(Retry, { while: () => false }),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
/** Apply the throttling retry policy (retries throttling errors indefinitely). */
|
|
51
|
+
export const throttling = policy(throttlingFactory);
|
|
52
|
+
|
|
53
|
+
/** Apply the transient retry policy (retries all transient errors indefinitely). */
|
|
54
|
+
export const transient = policy(transientFactory);
|