the-moby-effect
Version:
Moby/Docker API client built using effect-ts
88 lines • 3.69 kB
JavaScript
import * as Effect from "effect/Effect";
import * as Function from "effect/Function";
import * as Layer from "effect/Layer";
import * as internalAgnostic from "./agnostic.js";
import * as internalConnection from "./connection.js";
/** @internal */
export const makeNodeSshAgent = (httpLazy, ssh2Lazy, connectionOptions) => new class extends httpLazy.Agent {
// The ssh client that will be connecting to the server
sshClient;
// How to connect to the remote server and where the moby socket is located.
connectConfig;
constructor(ssh2ConnectConfig, agentOptions) {
super(agentOptions);
this.sshClient = new ssh2Lazy.Client();
this.connectConfig = ssh2ConnectConfig;
}
/**
* When creating a new connection, first start by trying to connect to
* the remote server over ssh. Then, if that was successful, we send a
* forwardOurStreamLocal request which is an OpenSSH extension that
* opens a connection to the unix domain socket at socketPath on the
* remote server and forwards traffic.
*
* @since 1.0.0
* @see https://nodejs.org/api/http.html#agentcreateconnectionoptions-callback
*/
createConnection(_options, callback) {
this.sshClient.on("ready", () => {
this.sshClient.openssh_forwardOutStreamLocal(this.connectConfig.remoteSocketPath, (error, stream) => {
if (error) {
this.sshClient.end();
return callback(error);
}
stream.once("close", () => {
stream.end();
stream.destroy();
this.sshClient.end();
});
callback(undefined, stream);
});
}).on("error", error => callback(error, undefined)).connect(this.connectConfig);
}
}(connectionOptions);
/** @internal */
export const getNodeAgent = connectionOptions => Function.pipe(Effect.all({
httpLazy: Effect.promise(() => import("node:http")),
httpsLazy: Effect.promise(() => import("node:https")),
nodeHttpClientLazy: Effect.promise(() => import("@effect/platform-node/NodeHttpClient"))
}, {
concurrency: 3
}), Effect.flatMap(({
httpLazy,
httpsLazy,
nodeHttpClientLazy
}) => {
const AcquireNodeHttpAgent = internalConnection.MobyConnectionOptions.$match({
http: options => Effect.succeed(new httpLazy.Agent({
host: options.host,
port: options.port
})),
socket: options => Effect.succeed(new httpLazy.Agent({
socketPath: options.socketPath
})),
ssh: options => Effect.map(Effect.promise(() => import("ssh2")), ssh2Lazy => makeNodeSshAgent(httpLazy, ssh2Lazy, options)),
https: options => Effect.succeed(new httpsLazy.Agent({
ca: options.ca,
key: options.key,
cert: options.cert,
host: options.host,
port: options.port,
passphrase: options.passphrase
}))
});
const releaseNodeHttpAgent = agent => Effect.sync(() => agent.destroy());
const resource = Effect.acquireRelease(AcquireNodeHttpAgent(connectionOptions), releaseNodeHttpAgent);
return Effect.map(resource, agent => ({
http: agent,
https: agent,
[nodeHttpClientLazy.HttpAgentTypeId]: nodeHttpClientLazy.HttpAgentTypeId
}));
}));
/** @internal */
export const makeNodeHttpClientLayer = connectionOptions => {
const nodeHttpClientLayer = Function.pipe(Effect.promise(() => import("@effect/platform-node/NodeHttpClient")), Effect.map(nodeHttpClientLazy => Layer.provide(nodeHttpClientLazy.layerWithoutAgent, Layer.scoped(nodeHttpClientLazy.HttpAgent, getNodeAgent(connectionOptions)))), Layer.unwrapEffect);
const agnosticHttpClientLayer = internalAgnostic.makeAgnosticLayer(connectionOptions);
return Layer.provide(agnosticHttpClientLayer, nodeHttpClientLayer);
};
//# sourceMappingURL=node.js.map