extend
@rotorsoft/act-root / act/src / extend
Function: extend()
extend<
S,T>(source,schema,target?):Readonly<S&T>
Defined in: libs/act/src/utils.ts:392
Validates and merges configuration objects.
This function first validates the source object against a Zod schema using validate, then merges it with an optional target object. The source properties override target properties in the result.
Primarily used for configuration management where you want to:
- Define default configuration values
- Load environment-specific overrides
- Validate the final configuration
The framework uses this internally for the config function.
Type Parameters
S
S extends Record<string, unknown>
Source object type (must be a record)
T
T extends Record<string, unknown>
Target object type (must be a record)
Parameters
source
Readonly<S>
The source object to validate and use as overrides
schema
ZodType<S>
Zod schema to validate the source against
target?
Readonly<T>
Optional target object with default values
Returns
Readonly<S & T>
Merged object with validated source overriding target
Throws
ValidationError if source fails schema validation
Examples
import { extend } from "@rotorsoft/act";
import { z } from "zod";
const ConfigSchema = z.object({
host: z.string(),
port: z.number(),
debug: z.boolean()
});
const defaults = { host: "localhost", port: 3000, debug: false };
const overrides = { port: 8080, debug: true };
const config = extend(overrides, ConfigSchema, defaults);
// Result: { host: "localhost", port: 8080, debug: true }
import { extend } from "@rotorsoft/act";
import { z } from "zod";
const DbConfigSchema = z.object({
host: z.string(),
port: z.number(),
database: z.string(),
user: z.string(),
password: z.string()
});
const defaults = {
host: "localhost",
port: 5432,
database: "myapp_dev",
user: "postgres",
password: "dev"
};
const envConfig = {
host: process.env.DB_HOST || "localhost",
port: parseInt(process.env.DB_PORT || "5432"),
database: process.env.DB_NAME || "myapp_dev",
user: process.env.DB_USER || "postgres",
password: process.env.DB_PASSWORD || "dev"
};
// Validates environment config and merges with defaults
const dbConfig = extend(envConfig, DbConfigSchema, defaults);
// This is how Act's config() function uses extend internally:
import { extend } from "@rotorsoft/act";
import { z } from "zod";
const BaseSchema = z.object({
env: z.enum(["development", "test", "staging", "production"]),
logLevel: z.enum(["fatal", "error", "warn", "info", "debug", "trace"]),
sleepMs: z.number().int().min(0).max(5000)
});
const packageData = { name: "my-app", version: "1.0.0" };
const runtimeConfig = { env: "production", logLevel: "info", sleepMs: 100 };
const config = extend(
{ ...packageData, ...runtimeConfig },
BaseSchema,
packageData
);
import { extend, ValidationError } from "@rotorsoft/act";
import { z } from "zod";
const schema = z.object({
apiKey: z.string().min(32),
timeout: z.number().positive()
});
try {
const config = extend(
{ apiKey: "short", timeout: -1 },
schema
);
} catch (error) {
if (error instanceof ValidationError) {
console.error("Invalid configuration:", error.details);
}
}
See
- validate for validation details
- config for framework configuration
- ValidationError for error handling