# @probitas/client-redis > Version: 0.5.0 Redis client for [Probitas](https://github.com/probitas-test/probitas) scenario testing framework. This package provides a Redis client designed for integration testing of applications using Redis. ## Features - **Data Structures**: Strings, Hashes, Lists, Sets, Sorted Sets - **Pub/Sub**: Publish and subscribe to channels - **Transactions**: Atomic operations with MULTI/EXEC - **Raw Commands**: Execute any Redis command via `command()` - **Resource Management**: Implements `AsyncDisposable` for proper cleanup ## Installation ```bash deno add jsr:@probitas/client-redis ``` ## Quick Start ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379/0", }); // String operations await client.set("user:1:name", "Alice", { ex: 3600 }); const result = await client.get("user:1:name"); console.log("Name:", result.value); // Hash operations await client.hset("user:1", "email", "alice@example.com"); const email = await client.hget("user:1", "email"); console.log("Email:", email.value); // List operations await client.rpush("queue", ["job1", "job2", "job3"]); const job = await client.lpop("queue"); console.log("Job:", job.value); await client.close(); ``` ## Transactions ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379" }); // Atomic transaction const tx = client.multi(); tx.incr("counter"); tx.get("counter"); await tx.exec(); await client.close(); ``` ## Pub/Sub ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379" }); // Subscribe to a channel const subscription = client.subscribe("events"); for await (const message of subscription) { console.log("Received:", message.message); break; } // Publish to a channel await client.publish("events", JSON.stringify({ type: "update" })); await client.close(); ``` ## Connection Configuration ```ts import { createRedisClient } from "@probitas/client-redis"; // Using URL string const client1 = await createRedisClient({ url: "redis://localhost:6379" }); // Using URL with password and database const client2 = await createRedisClient({ url: "redis://:secret@localhost:6379/1" }); // Using config object const client3 = await createRedisClient({ url: { host: "localhost", port: 6379, password: "secret", db: 1 }, }); await client1.close(); await client2.close(); await client3.close(); ``` ## Using with `using` Statement ```ts import { createRedisClient } from "@probitas/client-redis"; await using client = await createRedisClient({ url: "redis://localhost:6379" }); await client.set("test", "value"); const result = await client.get("test"); console.log(result.value); // Client automatically closed when block exits ``` ## Related Packages | Package | Description | |---------|-------------| | [`@probitas/client`](https://jsr.io/@probitas/client) | Core utilities and types | | [`@probitas/client-deno-kv`](https://jsr.io/@probitas/client-deno-kv) | Deno KV client | ## Links - [GitHub Repository](https://github.com/probitas-test/probitas-client) - [Probitas Framework](https://github.com/probitas-test/probitas) - [Redis](https://redis.io/) ## Classes ### `RedisError` ```typescript class RedisError extends ClientError ``` Base error class for Redis client errors. **Constructor:** ```typescript new RedisError(message: string, _: unknown, options?: RedisErrorOptions) ``` **Properties:** - [readonly] `name`: `string` - [readonly] `code?`: `string` --- ### `RedisConnectionError` ```typescript class RedisConnectionError extends RedisError ``` Error thrown when a Redis connection cannot be established. **Constructor:** ```typescript new RedisConnectionError(message: string, options?: RedisErrorOptions) ``` **Properties:** - [readonly] `name`: `string` - [readonly] `kind`: `"connection"` --- ### `RedisCommandError` ```typescript class RedisCommandError extends RedisError ``` Error thrown when a Redis command fails. **Constructor:** ```typescript new RedisCommandError(message: string, options: RedisCommandErrorOptions) ``` **Properties:** - [readonly] `name`: `string` - [readonly] `kind`: `"command"` - [readonly] `command`: `string` --- ### `RedisScriptError` ```typescript class RedisScriptError extends RedisError ``` Error thrown when a Redis Lua script fails. **Constructor:** ```typescript new RedisScriptError(message: string, options: RedisScriptErrorOptions) ``` **Properties:** - [readonly] `name`: `string` - [readonly] `kind`: `"script"` - [readonly] `script`: `string` --- ## Interfaces ### `RedisCommandOptions` ```typescript interface RedisCommandOptions extends CommonOptions ``` Redis command options. Extends CommonOptions with Redis-specific behavior options. **Properties:** - [readonly] `throwOnError?`: `boolean` — Whether to throw an error when the operation fails. When `true`, failures will throw an error instead of returning a result with `ok: false`. --- ### `RedisSetOptions` ```typescript interface RedisSetOptions extends RedisCommandOptions ``` Redis SET options **Properties:** - [readonly] `ex?`: `number` — Expiration in seconds - [readonly] `px?`: `number` — Expiration in milliseconds - [readonly] `nx?`: `boolean` — Only set if key does not exist - [readonly] `xx?`: `boolean` — Only set if key exists --- ### `RedisMessage` ```typescript interface RedisMessage ``` Redis Pub/Sub message **Properties:** - [readonly] `channel`: `string` - [readonly] `message`: `string` --- ### `RedisConnectionConfig` ```typescript interface RedisConnectionConfig extends CommonConnectionConfig ``` Redis connection configuration. Extends CommonConnectionConfig with Redis-specific options. **Properties:** - [readonly] `db?`: `number` — Database index. --- ### `RedisClientConfig` ```typescript interface RedisClientConfig extends CommonOptions ``` Redis client configuration. **Properties:** - [readonly] `url`: `string | RedisConnectionConfig` — Redis connection URL or configuration object. - [readonly] `throwOnError?`: `boolean` — Whether to throw an error when operations fail. When `true`, failures will throw an error instead of returning a result with `ok: false`. This can be overridden per-command. --- ### `RedisTransaction` ```typescript interface RedisTransaction ``` Redis transaction interface **Methods:** ```typescript get(key: string): this ``` ```typescript set(key: string, value: string, options?: RedisSetOptions): this ``` ```typescript del(_: string[]): this ``` ```typescript incr(key: string): this ``` ```typescript decr(key: string): this ``` ```typescript hget(key: string, field: string): this ``` ```typescript hset(key: string, field: string, value: string): this ``` ```typescript hgetall(key: string): this ``` ```typescript hdel(key: string, _: string[]): this ``` ```typescript lpush(key: string, _: string[]): this ``` ```typescript rpush(key: string, _: string[]): this ``` ```typescript lpop(key: string): this ``` ```typescript rpop(key: string): this ``` ```typescript lrange(key: string, start: number, stop: number): this ``` ```typescript llen(key: string): this ``` ```typescript sadd(key: string, _: string[]): this ``` ```typescript srem(key: string, _: string[]): this ``` ```typescript smembers(key: string): this ``` ```typescript sismember(key: string, member: string): this ``` ```typescript zadd(key: string, _: { score: number; member: string }[]): this ``` ```typescript zrange(key: string, start: number, stop: number): this ``` ```typescript zscore(key: string, member: string): this ``` ```typescript exec(options?: RedisCommandOptions): Promise> ``` ```typescript discard(): void ``` --- ### `RedisClient` ```typescript interface RedisClient extends AsyncDisposable ``` Redis client interface **Properties:** - [readonly] `config`: `RedisClientConfig` **Methods:** ```typescript get(key: string, options?: RedisCommandOptions): Promise ``` ```typescript set( key: string, value: string, options?: RedisSetOptions, ): Promise ``` ```typescript del(keys: string[], options?: RedisCommandOptions): Promise ``` ```typescript incr(key: string, options?: RedisCommandOptions): Promise ``` ```typescript decr(key: string, options?: RedisCommandOptions): Promise ``` ```typescript hget( key: string, field: string, options?: RedisCommandOptions, ): Promise ``` ```typescript hset( key: string, field: string, value: string, options?: RedisCommandOptions, ): Promise ``` ```typescript hgetall(key: string, options?: RedisCommandOptions): Promise ``` ```typescript hdel( key: string, fields: string[], options?: RedisCommandOptions, ): Promise ``` ```typescript lpush( key: string, values: string[], options?: RedisCommandOptions, ): Promise ``` ```typescript rpush( key: string, values: string[], options?: RedisCommandOptions, ): Promise ``` ```typescript lpop(key: string, options?: RedisCommandOptions): Promise ``` ```typescript rpop(key: string, options?: RedisCommandOptions): Promise ``` ```typescript lrange( key: string, start: number, stop: number, options?: RedisCommandOptions, ): Promise ``` ```typescript llen(key: string, options?: RedisCommandOptions): Promise ``` ```typescript sadd( key: string, members: string[], options?: RedisCommandOptions, ): Promise ``` ```typescript srem( key: string, members: string[], options?: RedisCommandOptions, ): Promise ``` ```typescript smembers(key: string, options?: RedisCommandOptions): Promise ``` ```typescript sismember( key: string, member: string, options?: RedisCommandOptions, ): Promise> ``` ```typescript zadd( key: string, entries: { score: number; member: string }[], options?: RedisCommandOptions, ): Promise ``` ```typescript zrange( key: string, start: number, stop: number, options?: RedisCommandOptions, ): Promise ``` ```typescript zscore( key: string, member: string, options?: RedisCommandOptions, ): Promise> ``` ```typescript publish( channel: string, message: string, options?: RedisCommandOptions, ): Promise ``` ```typescript subscribe(channel: string): AsyncIterable ``` ```typescript multi(): RedisTransaction ``` ```typescript command( cmd: string, args: unknown[], options?: RedisCommandOptions, ): Promise> ``` ```typescript close(): Promise ``` --- ### `RedisGetResultSuccess` ```typescript interface RedisGetResultSuccess extends RedisGetResultBase ``` Successful GET result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `string | null` --- ### `RedisGetResultError` ```typescript interface RedisGetResultError extends RedisGetResultBase ``` GET result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisGetResultFailure` ```typescript interface RedisGetResultFailure extends RedisGetResultBase ``` GET result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisSetResultSuccess` ```typescript interface RedisSetResultSuccess extends RedisSetResultBase ``` Successful SET result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `"OK"` --- ### `RedisSetResultError` ```typescript interface RedisSetResultError extends RedisSetResultBase ``` SET result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisSetResultFailure` ```typescript interface RedisSetResultFailure extends RedisSetResultBase ``` SET result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisCountResultSuccess` ```typescript interface RedisCountResultSuccess extends RedisCountResultBase ``` Successful count result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `number` --- ### `RedisCountResultError` ```typescript interface RedisCountResultError extends RedisCountResultBase ``` Count result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisCountResultFailure` ```typescript interface RedisCountResultFailure extends RedisCountResultBase ``` Count result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisArrayResultSuccess` ```typescript interface RedisArrayResultSuccess extends RedisArrayResultBase ``` Successful array result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `readonly T[]` --- ### `RedisArrayResultError` ```typescript interface RedisArrayResultError extends RedisArrayResultBase ``` Array result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisArrayResultFailure` ```typescript interface RedisArrayResultFailure extends RedisArrayResultBase ``` Array result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisHashResultSuccess` ```typescript interface RedisHashResultSuccess extends RedisHashResultBase ``` Successful hash result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `Record` --- ### `RedisHashResultError` ```typescript interface RedisHashResultError extends RedisHashResultBase ``` Hash result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisHashResultFailure` ```typescript interface RedisHashResultFailure extends RedisHashResultBase ``` Hash result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisCommonResultSuccess` ```typescript interface RedisCommonResultSuccess extends RedisCommonResultBase ``` Successful common result. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `true` - [readonly] `error`: `null` - [readonly] `value`: `T` --- ### `RedisCommonResultError` ```typescript interface RedisCommonResultError extends RedisCommonResultBase ``` Common result with Redis error. **Properties:** - [readonly] `processed`: `true` - [readonly] `ok`: `false` - [readonly] `error`: `RedisOperationError` - [readonly] `value`: `null` --- ### `RedisCommonResultFailure` ```typescript interface RedisCommonResultFailure extends RedisCommonResultBase ``` Common result with connection failure. **Properties:** - [readonly] `processed`: `false` - [readonly] `ok`: `false` - [readonly] `error`: `RedisFailureError` - [readonly] `value`: `null` --- ### `RedisErrorOptions` ```typescript interface RedisErrorOptions extends ErrorOptions ``` Options for Redis errors. **Properties:** - [readonly] `code?`: `string` --- ### `RedisCommandErrorOptions` ```typescript interface RedisCommandErrorOptions extends RedisErrorOptions ``` Options for Redis command errors. **Properties:** - [readonly] `command`: `string` --- ### `RedisScriptErrorOptions` ```typescript interface RedisScriptErrorOptions extends RedisErrorOptions ``` Options for Redis script errors. **Properties:** - [readonly] `script`: `string` --- ## Functions ### `createRedisClient` ```typescript async function createRedisClient( config: RedisClientConfig, ): Promise ``` Create a new Redis client instance. The client provides comprehensive Redis data structure support including strings, hashes, lists, sets, sorted sets, pub/sub, and transactions. **Parameters:** - `config`: `RedisClientConfig` — - Redis client configuration **Returns:** `Promise` A promise resolving to a new Redis client instance **Example:** Using URL string ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379/0", }); await client.set("key", "value"); const result = await client.get("key"); if (result.ok) { console.log(result.value); // "value" } await client.close(); ``` Using connection config object ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: { host: "localhost", port: 6379, password: "secret", db: 0, }, }); await client.close(); ``` Set with expiration ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379" }); const sessionData = JSON.stringify({ userId: "123" }); const data = "temporary value"; // Set key with 1 hour TTL await client.set("session", sessionData, { ex: 3600 }); // Set key with 5 second TTL in milliseconds await client.set("temp", data, { px: 5000 }); await client.close(); ``` Hash operations ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379" }); await client.hset("user:123", "name", "Alice"); await client.hset("user:123", "email", "alice@example.com"); const user = await client.hgetall("user:123"); if (user.ok) { console.log(user.value); // { name: "Alice", email: "alice@example.com" } } await client.close(); ``` Pub/Sub ```ts import { createRedisClient } from "@probitas/client-redis"; const client = await createRedisClient({ url: "redis://localhost:6379" }); // Subscribe to channel (this would run indefinitely in practice) // for await (const message of client.subscribe("events")) { // console.log("Received:", message.message); // } // Publish to channel await client.publish("events", JSON.stringify({ type: "user.created" })); await client.close(); ``` Using `await using` for automatic cleanup ```ts import { createRedisClient } from "@probitas/client-redis"; await using client = await createRedisClient({ url: "redis://localhost:6379", }); await client.set("test", "value"); // Client automatically closed when scope exits ``` --- ## Types ### `RedisFailureError` ```typescript type RedisFailureError = RedisConnectionError | AbortError | TimeoutError ``` Error types that indicate the operation was not processed. These are errors that occur before the operation reaches the Redis server. --- ### `RedisOperationError` ```typescript type RedisOperationError = RedisCommandError | RedisScriptError | RedisError ``` Error types that indicate the operation was processed but failed. These are errors returned by the Redis server. --- ### `RedisGetResult` ```typescript type RedisGetResult = RedisGetResultSuccess | RedisGetResultError | RedisGetResultFailure ``` Redis GET result. --- ### `RedisSetResult` ```typescript type RedisSetResult = RedisSetResultSuccess | RedisSetResultError | RedisSetResultFailure ``` Redis SET result. --- ### `RedisCountResult` ```typescript type RedisCountResult = RedisCountResultSuccess | RedisCountResultError | RedisCountResultFailure ``` Redis numeric result (DEL, LPUSH, SADD, etc.). --- ### `RedisArrayResult` ```typescript type RedisArrayResult = RedisArrayResultSuccess | RedisArrayResultError | RedisArrayResultFailure ``` Redis array result (LRANGE, SMEMBERS, etc.). --- ### `RedisHashResult` ```typescript type RedisHashResult = RedisHashResultSuccess | RedisHashResultError | RedisHashResultFailure ``` Redis hash result (HGETALL). --- ### `RedisCommonResult` ```typescript type RedisCommonResult = RedisCommonResultSuccess | RedisCommonResultError | RedisCommonResultFailure ``` Redis operation result (common/generic). Used for operations without a more specific result type. --- ### `RedisResult` ```typescript type RedisResult = RedisCommonResult | RedisGetResult | RedisSetResult | RedisCountResult | RedisArrayResult | RedisHashResult ``` Union of all Redis result types. --- ## Related Links ### This Package - [`RedisArrayResult`](https://probitas-test.github.io/documents/api/client-redis#RedisArrayResult) - [`RedisArrayResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisArrayResultError) - [`RedisArrayResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisArrayResultFailure) - [`RedisArrayResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisArrayResultSuccess) - [`RedisClient`](https://probitas-test.github.io/documents/api/client-redis#RedisClient) - [`RedisClientConfig`](https://probitas-test.github.io/documents/api/client-redis#RedisClientConfig) - [`RedisCommandError`](https://probitas-test.github.io/documents/api/client-redis#RedisCommandError) - [`RedisCommandErrorOptions`](https://probitas-test.github.io/documents/api/client-redis#RedisCommandErrorOptions) - [`RedisCommandOptions`](https://probitas-test.github.io/documents/api/client-redis#RedisCommandOptions) - [`RedisCommonResult`](https://probitas-test.github.io/documents/api/client-redis#RedisCommonResult) - [`RedisCommonResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisCommonResultError) - [`RedisCommonResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisCommonResultFailure) - [`RedisCommonResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisCommonResultSuccess) - [`RedisConnectionConfig`](https://probitas-test.github.io/documents/api/client-redis#RedisConnectionConfig) - [`RedisConnectionError`](https://probitas-test.github.io/documents/api/client-redis#RedisConnectionError) - [`RedisCountResult`](https://probitas-test.github.io/documents/api/client-redis#RedisCountResult) - [`RedisCountResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisCountResultError) - [`RedisCountResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisCountResultFailure) - [`RedisCountResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisCountResultSuccess) - [`RedisError`](https://probitas-test.github.io/documents/api/client-redis#RedisError) - [`RedisErrorOptions`](https://probitas-test.github.io/documents/api/client-redis#RedisErrorOptions) - [`RedisFailureError`](https://probitas-test.github.io/documents/api/client-redis#RedisFailureError) - [`RedisGetResult`](https://probitas-test.github.io/documents/api/client-redis#RedisGetResult) - [`RedisGetResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisGetResultError) - [`RedisGetResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisGetResultFailure) - [`RedisGetResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisGetResultSuccess) - [`RedisHashResult`](https://probitas-test.github.io/documents/api/client-redis#RedisHashResult) - [`RedisHashResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisHashResultError) - [`RedisHashResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisHashResultFailure) - [`RedisHashResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisHashResultSuccess) - [`RedisMessage`](https://probitas-test.github.io/documents/api/client-redis#RedisMessage) - [`RedisOperationError`](https://probitas-test.github.io/documents/api/client-redis#RedisOperationError) - [`RedisScriptError`](https://probitas-test.github.io/documents/api/client-redis#RedisScriptError) - [`RedisScriptErrorOptions`](https://probitas-test.github.io/documents/api/client-redis#RedisScriptErrorOptions) - [`RedisSetOptions`](https://probitas-test.github.io/documents/api/client-redis#RedisSetOptions) - [`RedisSetResult`](https://probitas-test.github.io/documents/api/client-redis#RedisSetResult) - [`RedisSetResultError`](https://probitas-test.github.io/documents/api/client-redis#RedisSetResultError) - [`RedisSetResultFailure`](https://probitas-test.github.io/documents/api/client-redis#RedisSetResultFailure) - [`RedisSetResultSuccess`](https://probitas-test.github.io/documents/api/client-redis#RedisSetResultSuccess) - [`RedisTransaction`](https://probitas-test.github.io/documents/api/client-redis#RedisTransaction) ### Other Packages - [`AbortError`](https://probitas-test.github.io/documents/api/client#AbortError) (@probitas/client) - [`CommonConnectionConfig`](https://probitas-test.github.io/documents/api/client#CommonConnectionConfig) (@probitas/client) - [`CommonOptions`](https://probitas-test.github.io/documents/api/client#CommonOptions) (@probitas/client) - [`TimeoutError`](https://probitas-test.github.io/documents/api/client#TimeoutError) (@probitas/client) ### Built-in Types - [`AsyncIterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) - [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) - [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type) --- *Last updated: 2026-01-12*