rightsize 0.4.0 → 0.5.0

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/README.md CHANGED
@@ -62,7 +62,7 @@ import "rightsize/backend-msb";
62
62
  import "rightsize/backend-docker";
63
63
  ```
64
64
 
65
- Drive any image directly with `GenericContainer`, or use one of eighteen
65
+ Drive any image directly with `GenericContainer`, or use one of twenty-one
66
66
  preconfigured modules:
67
67
 
68
68
  ```ts
@@ -88,6 +88,7 @@ a `GenericContainer` subclass, so the fluent builders (`withEnv`,
88
88
  | Module | Helpers |
89
89
  |---|---|
90
90
  | `RedisContainer` | `uri` |
91
+ | `ValkeyContainer` | `uri` (`redis://` scheme — Valkey speaks the Redis wire protocol) |
91
92
  | `MemcachedContainer` | `address` |
92
93
  | `ArangoContainer` | `endpoint`; `withRootPassword(...)` to enable auth (default: no-auth) |
93
94
  | `MongoDBContainer` | `connectionString`, `replicaSetUrl` (alias) — single-node replica set, auto-initiated |
@@ -105,11 +106,14 @@ a `GenericContainer` subclass, so the fluent builders (`withEnv`,
105
106
  | `Neo4jContainer` | `httpUrl`, `boltUrl`, `username`, `password`; `withPassword(...)` — HTTP Cypher endpoint (username fixed at `neo4j`) |
106
107
  | `FlociContainer` | `FlociContainer.aws()`/`.azure()`/`.gcp()` factories, `endpointUrl` — [floci.io](https://floci.io) cloud emulators (unsigned REST, no SDK needed) |
107
108
  | `FlinkContainer` | `restUrl`; `withTaskManager()` for a full session cluster — **Docker only**¹ |
109
+ | `MinIOContainer` | `endpointUrl`, `rootUser`, `rootPassword`; `withRootUser`/`withRootPassword(...)` — S3-compatible object store |
110
+ | `CassandraContainer` | `contactPoint`, `cqlPort`, `localDatacenter` |
108
111
 
109
112
  Some modules raise a memory floor for their image (`withMemoryLimit`):
110
113
  heavyweight JVM images - Spring Cloud Config, Keycloak, Neo4j, Flink
111
- (1024 MB) - and Pinot's multi-JVM QuickStart cluster (4096 MB) - need more
112
- than the microVM default. That's baked into the module; you don't set it.
114
+ (1024 MB), Cassandra (2560 MB) - and Pinot's multi-JVM QuickStart cluster
115
+ (4096 MB) - need more than the microVM default. That's baked into the
116
+ module; you don't set it.
113
117
  Every module's page under [`docs/modules/`](https://ngriaznov.github.io/rightsize-node/modules/)
114
118
  documents its exact image tag, wait strategy, and the measured reasoning
115
119
  behind these choices.
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * contracts plus the `registerBackend` registry, and the typed error
9
9
  * classes. This module depends on no backend — import `rightsize/backend-msb`
10
10
  * and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
11
- * for the eighteen preconfigured containers built on top of this surface.
11
+ * for the twenty-one preconfigured containers built on top of this surface.
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * contracts plus the `registerBackend` registry, and the typed error
9
9
  * classes. This module depends on no backend — import `rightsize/backend-msb`
10
10
  * and/or `rightsize/backend-docker` to register one, or `rightsize/modules`
11
- * for the eighteen preconfigured containers built on top of this surface.
11
+ * for the twenty-one preconfigured containers built on top of this surface.
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
@@ -0,0 +1,49 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ /**
3
+ * A single-node Cassandra container.
4
+ *
5
+ * ### `GPG_KEYS` must be overridden — this is the difference between booting and aborting
6
+ *
7
+ * `cassandra:5.0.8`'s baked-in `GPG_KEYS` build arg contains a literal TAB
8
+ * character, and msb 0.6.6 panics on any image whose baked env contains one
9
+ * — before the guest even boots:
10
+ *
11
+ * ```
12
+ * sandbox process exited (signal: 6 (SIGABRT)) before agent relay became available
13
+ * ```
14
+ *
15
+ * with `msb logs --source system` showing:
16
+ *
17
+ * ```
18
+ * panicked at msb_krun_vmm-0.1.25/src/builder.rs:1154: ... Err value: InvalidAscii
19
+ * ```
20
+ *
21
+ * `GPG_KEYS` is consumed only at image-build time (verifying the signing
22
+ * keys baked into that layer) — it has no effect on the running container,
23
+ * so overriding it to an empty, tab-free string here is safe and required.
24
+ * Without this override, `start()` never gets far enough to run its own
25
+ * wait strategy at all.
26
+ *
27
+ * ### Heap sized down, memory ceiling measured
28
+ *
29
+ * `MAX_HEAP_SIZE=512M`/`HEAP_NEWSIZE=128M` keep the JVM small; `2560` MB is
30
+ * the verified memory ceiling at that heap size.
31
+ *
32
+ * ### Readiness
33
+ *
34
+ * Anchored on the CQL native-transport log line (`Starting listening for
35
+ * CQL clients`), observed at 58s on a quiet local machine. 300s absorbs a
36
+ * loaded-host boot without masking a real hang — Cassandra is heavier than
37
+ * either Keycloak or MySQL, both of which carry 180s in this library.
38
+ */
39
+ export declare class CassandraContainer extends GenericContainer {
40
+ constructor(image?: string);
41
+ static start(image?: string): Promise<CassandraContainer>;
42
+ /** `<host>:<port>` for the running container — the shape most CQL drivers want for a contact point. */
43
+ get contactPoint(): string;
44
+ /** The mapped CQL native-transport port. */
45
+ get cqlPort(): number;
46
+ /** This single node's local datacenter name — required by drivers (e.g. the DataStax Node driver) that insist on an explicit value at connect time. */
47
+ get localDatacenter(): string;
48
+ }
49
+ //# sourceMappingURL=cassandra.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassandra.d.ts","sourceRoot":"","sources":["../../src/modules/cassandra.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAMhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,kBAAmB,SAAQ,gBAAgB;gBAC1C,KAAK,SAAoB;WAaf,KAAK,CAAC,KAAK,SAAoB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAInF,uGAAuG;IACvG,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,4CAA4C;IAC5C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,uJAAuJ;IACvJ,IAAI,eAAe,IAAI,MAAM,CAE5B;CACF"}
@@ -0,0 +1,69 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ import { Wait } from "../core/wait.js";
3
+ const CQL_PORT = 9042;
4
+ const STARTUP_TIMEOUT_MS = 300_000;
5
+ /**
6
+ * A single-node Cassandra container.
7
+ *
8
+ * ### `GPG_KEYS` must be overridden — this is the difference between booting and aborting
9
+ *
10
+ * `cassandra:5.0.8`'s baked-in `GPG_KEYS` build arg contains a literal TAB
11
+ * character, and msb 0.6.6 panics on any image whose baked env contains one
12
+ * — before the guest even boots:
13
+ *
14
+ * ```
15
+ * sandbox process exited (signal: 6 (SIGABRT)) before agent relay became available
16
+ * ```
17
+ *
18
+ * with `msb logs --source system` showing:
19
+ *
20
+ * ```
21
+ * panicked at msb_krun_vmm-0.1.25/src/builder.rs:1154: ... Err value: InvalidAscii
22
+ * ```
23
+ *
24
+ * `GPG_KEYS` is consumed only at image-build time (verifying the signing
25
+ * keys baked into that layer) — it has no effect on the running container,
26
+ * so overriding it to an empty, tab-free string here is safe and required.
27
+ * Without this override, `start()` never gets far enough to run its own
28
+ * wait strategy at all.
29
+ *
30
+ * ### Heap sized down, memory ceiling measured
31
+ *
32
+ * `MAX_HEAP_SIZE=512M`/`HEAP_NEWSIZE=128M` keep the JVM small; `2560` MB is
33
+ * the verified memory ceiling at that heap size.
34
+ *
35
+ * ### Readiness
36
+ *
37
+ * Anchored on the CQL native-transport log line (`Starting listening for
38
+ * CQL clients`), observed at 58s on a quiet local machine. 300s absorbs a
39
+ * loaded-host boot without masking a real hang — Cassandra is heavier than
40
+ * either Keycloak or MySQL, both of which carry 180s in this library.
41
+ */
42
+ export class CassandraContainer extends GenericContainer {
43
+ constructor(image = "cassandra:5.0.8") {
44
+ super(image);
45
+ this.withExposedPorts(CQL_PORT)
46
+ // Required — see the class doc for the exact panic this avoids.
47
+ .withEnv("GPG_KEYS", "")
48
+ .withEnv("MAX_HEAP_SIZE", "512M")
49
+ .withEnv("HEAP_NEWSIZE", "128M")
50
+ .withMemoryLimit(2560)
51
+ .waitingFor(Wait.forLogMessage(".*Starting listening for CQL clients.*", 1).withStartupTimeout(STARTUP_TIMEOUT_MS));
52
+ }
53
+ static async start(image = "cassandra:5.0.8") {
54
+ return (await new CassandraContainer(image).start());
55
+ }
56
+ /** `<host>:<port>` for the running container — the shape most CQL drivers want for a contact point. */
57
+ get contactPoint() {
58
+ return `${this.host}:${this.getMappedPort(CQL_PORT)}`;
59
+ }
60
+ /** The mapped CQL native-transport port. */
61
+ get cqlPort() {
62
+ return this.getMappedPort(CQL_PORT);
63
+ }
64
+ /** This single node's local datacenter name — required by drivers (e.g. the DataStax Node driver) that insist on an explicit value at connect time. */
65
+ get localDatacenter() {
66
+ return "datacenter1";
67
+ }
68
+ }
69
+ //# sourceMappingURL=cassandra.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassandra.js","sourceRoot":"","sources":["../../src/modules/cassandra.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,kBAAmB,SAAQ,gBAAgB;IACtD,YAAY,KAAK,GAAG,iBAAiB;QACnC,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;YAC7B,gEAAgE;aAC/D,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;aACvB,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC;aAChC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC;aAC/B,eAAe,CAAC,IAAI,CAAC;aACrB,UAAU,CACT,IAAI,CAAC,aAAa,CAAC,wCAAwC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CACvG,CAAC;IACN,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,iBAAiB;QACnD,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAuB,CAAC;IAC7E,CAAC;IAED,uGAAuG;IACvG,IAAI,YAAY;QACd,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxD,CAAC;IAED,4CAA4C;IAC5C,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,uJAAuJ;IACvJ,IAAI,eAAe;QACjB,OAAO,aAAa,CAAC;IACvB,CAAC;CACF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `rightsize/modules` — eighteen preconfigured containers.
2
+ * `rightsize/modules` — twenty-one preconfigured containers.
3
3
  *
4
4
  * Each module is a `GenericContainer` subclass with sensible defaults (image
5
5
  * tag, exposed ports, wait strategy, and any memory floor its image needs)
@@ -11,6 +11,7 @@
11
11
  * @packageDocumentation
12
12
  */
13
13
  export { RedisContainer } from "./redis.js";
14
+ export { ValkeyContainer } from "./valkey.js";
14
15
  export { MemcachedContainer, MemcachedRespondsStrategy } from "./memcached.js";
15
16
  export { ArangoContainer } from "./arango.js";
16
17
  export { MongoDBContainer } from "./mongodb.js";
@@ -28,4 +29,6 @@ export { KeycloakContainer } from "./keycloak.js";
28
29
  export { ClickHouseContainer } from "./clickhouse.js";
29
30
  export { Neo4jContainer } from "./neo4j.js";
30
31
  export { FlociContainer } from "./floci.js";
32
+ export { MinIOContainer } from "./minio.js";
33
+ export { CassandraContainer } from "./cassandra.js";
31
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `rightsize/modules` — eighteen preconfigured containers.
2
+ * `rightsize/modules` — twenty-one preconfigured containers.
3
3
  *
4
4
  * Each module is a `GenericContainer` subclass with sensible defaults (image
5
5
  * tag, exposed ports, wait strategy, and any memory floor its image needs)
@@ -11,6 +11,7 @@
11
11
  * @packageDocumentation
12
12
  */
13
13
  export { RedisContainer } from "./redis.js";
14
+ export { ValkeyContainer } from "./valkey.js";
14
15
  export { MemcachedContainer, MemcachedRespondsStrategy } from "./memcached.js";
15
16
  export { ArangoContainer } from "./arango.js";
16
17
  export { MongoDBContainer } from "./mongodb.js";
@@ -28,4 +29,6 @@ export { KeycloakContainer } from "./keycloak.js";
28
29
  export { ClickHouseContainer } from "./clickhouse.js";
29
30
  export { Neo4jContainer } from "./neo4j.js";
30
31
  export { FlociContainer } from "./floci.js";
32
+ export { MinIOContainer } from "./minio.js";
33
+ export { CassandraContainer } from "./cassandra.js";
31
34
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ /**
3
+ * A single-node MinIO container — an S3-compatible object store. Requires
4
+ * an explicit command: the image's default ENTRYPOINT alone does not serve,
5
+ * so this module always runs `server /data --console-address :9001`.
6
+ *
7
+ * `MINIO_ROOT_USER`/`MINIO_ROOT_PASSWORD` default to `testuser`/
8
+ * `testpassword`, not this library's usual `test`/`test` pair — MinIO
9
+ * itself rejects a root password shorter than 8 characters, so `test` (4
10
+ * characters) is a non-starter here.
11
+ *
12
+ * Exposes both the S3 API (9000, what `endpointUrl` wraps) and the web
13
+ * console (9001, published for anyone who wants to open it directly; no
14
+ * helper wraps it).
15
+ *
16
+ * Readiness is a protocol-aware HTTP check against `/minio/health/live` on
17
+ * the API port — verified answering 200 on the very first poll after boot.
18
+ */
19
+ export declare class MinIOContainer extends GenericContainer {
20
+ private rootUserState;
21
+ private rootPasswordState;
22
+ constructor(image?: string);
23
+ static start(image?: string): Promise<MinIOContainer>;
24
+ /** Overrides `MINIO_ROOT_USER` (default `testuser`). */
25
+ withRootUser(user: string): this;
26
+ /** Overrides `MINIO_ROOT_PASSWORD` (default `testpassword`). MinIO rejects anything shorter than 8 characters. */
27
+ withRootPassword(password: string): this;
28
+ /** The configured root user (default `testuser`). */
29
+ get rootUser(): string;
30
+ /** The configured root password (default `testpassword`). */
31
+ get rootPassword(): string;
32
+ /** The S3 API's base URL for the running container. */
33
+ get endpointUrl(): string;
34
+ }
35
+ //# sourceMappingURL=minio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minio.d.ts","sourceRoot":"","sources":["../../src/modules/minio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAMhE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,iBAAiB,CAAkB;gBAE/B,KAAK,SAA6C;WAcxC,KAAK,CAAC,KAAK,SAA6C,GAAG,OAAO,CAAC,cAAc,CAAC;IAIxG,wDAAwD;IACxD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKhC,kHAAkH;IAClH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKxC,qDAAqD;IACrD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,6DAA6D;IAC7D,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,uDAAuD;IACvD,IAAI,WAAW,IAAI,MAAM,CAExB;CACF"}
@@ -0,0 +1,64 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ import { Wait } from "../core/wait.js";
3
+ const API_PORT = 9000;
4
+ const CONSOLE_PORT = 9001;
5
+ /**
6
+ * A single-node MinIO container — an S3-compatible object store. Requires
7
+ * an explicit command: the image's default ENTRYPOINT alone does not serve,
8
+ * so this module always runs `server /data --console-address :9001`.
9
+ *
10
+ * `MINIO_ROOT_USER`/`MINIO_ROOT_PASSWORD` default to `testuser`/
11
+ * `testpassword`, not this library's usual `test`/`test` pair — MinIO
12
+ * itself rejects a root password shorter than 8 characters, so `test` (4
13
+ * characters) is a non-starter here.
14
+ *
15
+ * Exposes both the S3 API (9000, what `endpointUrl` wraps) and the web
16
+ * console (9001, published for anyone who wants to open it directly; no
17
+ * helper wraps it).
18
+ *
19
+ * Readiness is a protocol-aware HTTP check against `/minio/health/live` on
20
+ * the API port — verified answering 200 on the very first poll after boot.
21
+ */
22
+ export class MinIOContainer extends GenericContainer {
23
+ rootUserState = "testuser";
24
+ rootPasswordState = "testpassword";
25
+ constructor(image = "minio/minio:RELEASE.2025-09-07T16-13-09Z") {
26
+ super(image);
27
+ this.withExposedPorts(API_PORT, CONSOLE_PORT)
28
+ .withCommand("server", "/data", "--console-address", ":9001")
29
+ .withEnv("MINIO_ROOT_USER", this.rootUserState)
30
+ .withEnv("MINIO_ROOT_PASSWORD", this.rootPasswordState)
31
+ .waitingFor(Wait.forHttp("/minio/health/live").forPort(API_PORT));
32
+ // No withMemoryLimit override: the round-trip that verified this module
33
+ // ran at 1024 MB, but whether MinIO actually needs more than msb's
34
+ // default microVM sizing was never isolated in that pass — a floor
35
+ // belongs here once that's measured on its own, not assumed from a
36
+ // number that included the whole round-trip's overhead.
37
+ }
38
+ static async start(image = "minio/minio:RELEASE.2025-09-07T16-13-09Z") {
39
+ return (await new MinIOContainer(image).start());
40
+ }
41
+ /** Overrides `MINIO_ROOT_USER` (default `testuser`). */
42
+ withRootUser(user) {
43
+ this.rootUserState = user;
44
+ return this.withEnv("MINIO_ROOT_USER", user);
45
+ }
46
+ /** Overrides `MINIO_ROOT_PASSWORD` (default `testpassword`). MinIO rejects anything shorter than 8 characters. */
47
+ withRootPassword(password) {
48
+ this.rootPasswordState = password;
49
+ return this.withEnv("MINIO_ROOT_PASSWORD", password);
50
+ }
51
+ /** The configured root user (default `testuser`). */
52
+ get rootUser() {
53
+ return this.rootUserState;
54
+ }
55
+ /** The configured root password (default `testpassword`). */
56
+ get rootPassword() {
57
+ return this.rootPasswordState;
58
+ }
59
+ /** The S3 API's base URL for the running container. */
60
+ get endpointUrl() {
61
+ return `http://${this.host}:${this.getMappedPort(API_PORT)}`;
62
+ }
63
+ }
64
+ //# sourceMappingURL=minio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minio.js","sourceRoot":"","sources":["../../src/modules/minio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,cAAe,SAAQ,gBAAgB;IAC1C,aAAa,GAAG,UAAU,CAAC;IAC3B,iBAAiB,GAAG,cAAc,CAAC;IAE3C,YAAY,KAAK,GAAG,0CAA0C;QAC5D,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;aAC1C,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,CAAC;aAC5D,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC;aAC9C,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC,iBAAiB,CAAC;aACtD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpE,wEAAwE;QACxE,mEAAmE;QACnE,mEAAmE;QACnE,mEAAmE;QACnE,wDAAwD;IAC1D,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,0CAA0C;QAC5E,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAmB,CAAC;IACrE,CAAC;IAED,wDAAwD;IACxD,YAAY,CAAC,IAAY;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,kHAAkH;IAClH,gBAAgB,CAAC,QAAgB;QAC/B,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,qDAAqD;IACrD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,6DAA6D;IAC7D,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED,uDAAuD;IACvD,IAAI,WAAW;QACb,OAAO,UAAU,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC/D,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ /**
3
+ * A single-node Valkey container — the Redis-protocol-compatible fork,
4
+ * following `RedisContainer`'s shape exactly. Readiness is anchored on the
5
+ * same `Ready to accept connections tcp` log line Redis prints, for the
6
+ * same reason: on a loaded host, msb's loopback forwarder can accept and
7
+ * hold a TCP connection before the guest process is actually listening, so
8
+ * a bare port probe risks returning before the server serves.
9
+ *
10
+ * `uri` deliberately uses the `redis://` scheme, not `valkey://`: every
11
+ * client this library's tests and its users reach for — lettuce,
12
+ * node-redis, or raw RESP over TCP — parses `redis://`, and Valkey speaks
13
+ * that same wire protocol. This is not a copy-paste mistake.
14
+ */
15
+ export declare class ValkeyContainer extends GenericContainer {
16
+ constructor(image?: string);
17
+ static start(image?: string): Promise<ValkeyContainer>;
18
+ /** A `redis://` connection URI for the running container (see the class doc for why not `valkey://`). */
19
+ get uri(): string;
20
+ }
21
+ //# sourceMappingURL=valkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valkey.d.ts","sourceRoot":"","sources":["../../src/modules/valkey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,gBAAgB;gBACvC,KAAK,SAA6B;WAOxB,KAAK,CAAC,KAAK,SAA6B,GAAG,OAAO,CAAC,eAAe,CAAC;IAIzF,yGAAyG;IACzG,IAAI,GAAG,IAAI,MAAM,CAEhB;CACF"}
@@ -0,0 +1,32 @@
1
+ import { GenericContainer } from "../core/generic-container.js";
2
+ import { Wait } from "../core/wait.js";
3
+ const GUEST_PORT = 6379;
4
+ /**
5
+ * A single-node Valkey container — the Redis-protocol-compatible fork,
6
+ * following `RedisContainer`'s shape exactly. Readiness is anchored on the
7
+ * same `Ready to accept connections tcp` log line Redis prints, for the
8
+ * same reason: on a loaded host, msb's loopback forwarder can accept and
9
+ * hold a TCP connection before the guest process is actually listening, so
10
+ * a bare port probe risks returning before the server serves.
11
+ *
12
+ * `uri` deliberately uses the `redis://` scheme, not `valkey://`: every
13
+ * client this library's tests and its users reach for — lettuce,
14
+ * node-redis, or raw RESP over TCP — parses `redis://`, and Valkey speaks
15
+ * that same wire protocol. This is not a copy-paste mistake.
16
+ */
17
+ export class ValkeyContainer extends GenericContainer {
18
+ constructor(image = "valkey/valkey:9.1-alpine") {
19
+ super(image);
20
+ this.withExposedPorts(GUEST_PORT).waitingFor(Wait.forLogMessage(".*Ready to accept connections.*", 1));
21
+ // No withMemoryLimit override: verified booting and answering PING with
22
+ // no limit set beyond msb's default, well under 512 MB.
23
+ }
24
+ static async start(image = "valkey/valkey:9.1-alpine") {
25
+ return (await new ValkeyContainer(image).start());
26
+ }
27
+ /** A `redis://` connection URI for the running container (see the class doc for why not `valkey://`). */
28
+ get uri() {
29
+ return `redis://${this.host}:${this.getMappedPort(GUEST_PORT)}`;
30
+ }
31
+ }
32
+ //# sourceMappingURL=valkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valkey.js","sourceRoot":"","sources":["../../src/modules/valkey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,eAAgB,SAAQ,gBAAgB;IACnD,YAAY,KAAK,GAAG,0BAA0B;QAC5C,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvG,wEAAwE;QACxE,wDAAwD;IAC1D,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,0BAA0B;QAC5D,OAAO,CAAC,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAoB,CAAC;IACvE,CAAC;IAED,yGAAyG;IACzG,IAAI,GAAG;QACL,OAAO,WAAW,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;IAClE,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rightsize",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Testcontainers-style integration testing on microsandbox microVMs, with a Docker fallback and an await-using lifecycle. No Docker required.",
5
5
  "keywords": [
6
6
  "testcontainers",