feat: add base mod

This commit is contained in:
2024-07-19 18:49:37 +02:00
parent f1764732c3
commit 4ffcb4a2fa
8 changed files with 68 additions and 13 deletions

View File

@@ -3,8 +3,27 @@ import getPort from "port";
import psql, { type Sql } from "postgres"; import psql, { type Sql } from "postgres";
import type { Container } from "../docker/libraries/container.ts"; import type { Container } from "../docker/libraries/container.ts";
import { docker } from "../docker/mod.ts"; import { docker } from "../mod.ts";
/**
* @module
*
* Provides the ability to quickly run a postgres image in a docker instance.
*
* @example
* ```ts
* import { PostgresTestContainer } from "@valkyr/testcontainers/postgres";
*
* const container = await PostgresTestContainer.start("postgres:16");
*
* await container.create("db");
* await container.client("db")`SELECT 1`;
*
* console.log(container.url("db")); // => postgres://postgres:postgres@127.0.0.1:5432/db
*
* await container.stop();
* ```
*/
export class PostgresTestContainer { export class PostgresTestContainer {
private constructor( private constructor(
readonly container: Container, readonly container: Container,

View File

@@ -1,7 +1,8 @@
{ {
"name": "@valkyr/testcontainers", "name": "@valkyr/testcontainers",
"version": "1.0.1", "version": "1.0.2",
"exports": { "exports": {
".": "./mod.ts",
"./postgres": "./containers/postgres.ts" "./postgres": "./containers/postgres.ts"
}, },
"imports": { "imports": {
@@ -24,6 +25,15 @@
"fmt": { "fmt": {
"lineWidth": 120 "lineWidth": 120
}, },
"publish": {
"exclude": [
".eslint",
".github",
".vscode",
".gitignore",
"tests"
]
},
"tasks": { "tasks": {
"lint": "deno lint && npx eslint -c .eslint/eslint.config.mjs .", "lint": "deno lint && npx eslint -c .eslint/eslint.config.mjs .",
"test": "export ENVIRONMENT=testing && deno test --allow-all --unstable-ffi" "test": "export ENVIRONMENT=testing && deno test --allow-all --unstable-ffi"

View File

@@ -3,6 +3,20 @@ import { Container } from "./container.ts";
import { Image } from "./image.ts"; import { Image } from "./image.ts";
import { modem } from "./modem.ts"; import { modem } from "./modem.ts";
/**
* @module
*
* A simple wrapper for pulling a docker image, and creating docker containers.
*
* @example
* ```ts
* import { docker } from "@valkyr/testcontainers";
*
* await docker.pullImage("docker:image");
*
* const container = await docker.createContainer({ Image: "docker:image" });
* ```
*/
export class Docker { export class Docker {
/** /**
* Create a new docker container. * Create a new docker container.
@@ -12,7 +26,10 @@ export class Docker {
* @params config - The configuration for the container. * @params config - The configuration for the container.
* @params query - Query parameters. * @params query - Query parameters.
*/ */
async createContainer(config: Partial<ContainerConfig>, query: Partial<{ name: string; platform: string }> = {}) { async createContainer(
config: Partial<ContainerConfig>,
query: Partial<{ name: string; platform: string }> = {},
): Promise<Container> {
const { Id, Warnings } = await modem.post<{ Id: string; Warnings: string[] }>({ const { Id, Warnings } = await modem.post<{ Id: string; Warnings: string[] }>({
path: "/containers/create", path: "/containers/create",
query, query,
@@ -26,7 +43,7 @@ export class Docker {
* *
* @param image - The image to pull. * @param image - The image to pull.
*/ */
async pullImage(image: string) { async pullImage(image: string): Promise<void> {
await new Image().create({ fromImage: image }); await new Image().create({ fromImage: image });
} }
} }

View File

@@ -12,7 +12,7 @@ export class Exec {
* *
* @param body - Request body schema. * @param body - Request body schema.
*/ */
async start(body: Partial<StartSchema> = {}) { async start(body: Partial<StartSchema> = {}): Promise<void> {
await modem.post({ path: `/exec/${this.id}/start`, body }); await modem.post({ path: `/exec/${this.id}/start`, body });
await this.#endSignal(); await this.#endSignal();
} }
@@ -20,7 +20,7 @@ export class Exec {
/** /**
* Return low-level information about the exec instance. * Return low-level information about the exec instance.
*/ */
async inspect() { async inspect(): Promise<InspectResponse> {
return modem.get<InspectResponse>({ path: `/exec/${this.id}/json` }); return modem.get<InspectResponse>({ path: `/exec/${this.id}/json` });
} }
@@ -37,7 +37,7 @@ export class Exec {
* [TODO] Introduce a timeout signal in case we want to add a treshold to the * [TODO] Introduce a timeout signal in case we want to add a treshold to the
* running time. * running time.
*/ */
async #endSignal() { async #endSignal(): Promise<void> {
while (true) { while (true) {
const info = await this.inspect(); const info = await this.inspect();
if (info.Running === false) { if (info.Running === false) {

View File

@@ -1,7 +1,10 @@
import { Client, type Response } from "../../http/mod.ts"; import { Client, type Response } from "../../http/mod.ts";
class Modem { class Modem {
constructor(readonly options: Deno.ConnectOptions | Deno.UnixConnectOptions, readonly client = new Client(options)) {} constructor(
readonly options: Deno.ConnectOptions | Deno.UnixConnectOptions,
readonly client: Client = new Client(options),
) {}
/** /**
* Send a `POST` request to the Docker API. * Send a `POST` request to the Docker API.
@@ -59,7 +62,7 @@ class Modem {
} }
} }
export const modem = new Modem({ export const modem: Modem = new Modem({
path: "/var/run/docker.sock", path: "/var/run/docker.sock",
transport: "unix", transport: "unix",
}); });

View File

@@ -1,3 +0,0 @@
import { Docker } from "./libraries/docker.ts";
export const docker = new Docker();

View File

@@ -11,7 +11,7 @@ export class Client {
* closed when accessing the .stream on the response. Otherwise a manual .close must * closed when accessing the .stream on the response. Otherwise a manual .close must
* be executed on the response to ensure that the connection is cleaned up. * be executed on the response to ensure that the connection is cleaned up.
*/ */
get connection() { get connection(): Promise<Deno.UnixConn> | Promise<Deno.TcpConn> {
if ("path" in this.options) { if ("path" in this.options) {
return Deno.connect(this.options); return Deno.connect(this.options);
} }

9
mod.ts Normal file
View File

@@ -0,0 +1,9 @@
import { Docker } from "./docker/libraries/docker.ts";
export type { Container } from "./docker/libraries/container.ts";
export type { Docker } from "./docker/libraries/docker.ts";
export type { Exec } from "./docker/libraries/exec.ts";
export type { Image } from "./docker/libraries/image.ts";
export { modem } from "./docker/libraries/modem.ts";
export const docker: Docker = new Docker();