@debkit/schema
v1.2.0
Published
Type-safe value extraction and transformation from key-value records
Downloads
318
Maintainers
Readme
@debkit/schema
Type-safe value extraction and transformation from key-value records. Useful for config parsing, environment variables, API responses, or any Record<string, unknown> source.
Install
npm install @debkit/schemaThis will also install @debkit/types as a dependency.
API
Extractor
Extracts and transforms values from a key-value record with null safety.
import { Extractor } from '@debkit/schema';
const config = Extractor.from({
PORT: '3000',
HOST: 'localhost',
DEBUG: 'true',
OPTIONAL_KEY: undefined,
});
// throwOnNull: listed keys throw ConfigError if null
const { PORT, HOST, DEBUG, OPTIONAL_KEY } = config
.select({
PORT: 'number',
HOST: 'string',
DEBUG: 'boolean',
OPTIONAL_KEY: 'string',
})
.throwOnNull(['PORT', 'HOST']);
// PORT: 3000, HOST: 'localhost', DEBUG: true, OPTIONAL_KEY: null (no error)
// allowNull: listed keys are allowed to be null, rest throw
const result = config
.select({ PORT: 'number', HOST: 'string' })
.allowNull(['HOST']);
// PORT throws if null, HOST can be nullExtractor.from(records)
Creates a new extractor from a record.
.add(records)
Merges additional records into the extractor.
.select(properties).throwOnNull(keys) / .allowNull(keys)
Selects and transforms properties. Each property specifies a transform type:
'string'/'number'/'boolean'- primitive transforms['custom', (value) => result]- custom transform function{ primitive: 'number', fallback: 0 }- with fallback on error
Transformer
Static helpers for building complex transform descriptors.
Transformer.custom(fn)
Custom transform function.
import { Transformer } from '@debkit/schema';
const result = config.select({
API_URL: Transformer.custom((v) => new URL(String(v))),
}).throwOnNull(['API_URL']);Transformer.primitives(type, fallback)
Primitive with a fallback value on error.
config.select({
PORT: Transformer.primitives('number', 3000),
}).throwOnNull(['PORT']);
// Returns 3000 if PORT can't be converted to numberTransformer.enum(enumObject, fallback?)
Validates value against an enum (case-insensitive matching).
enum LogLevel { DEBUG = 'debug', INFO = 'info', ERROR = 'error' }
config.select({
LOG_LEVEL: Transformer.enum(LogLevel, LogLevel.INFO),
}).throwOnNull(['LOG_LEVEL']);Transformer.stringTypes(types, fallback?)
Validates value is one of the allowed string literals.
config.select({
ENV: Transformer.stringTypes(['dev', 'staging', 'prod'], 'dev'),
}).throwOnNull(['ENV']);Transformer.array(itemTransform, fallback?)
Transforms each element of an array value.
config.select({
PORTS: Transformer.array('number', [3000]),
}).throwOnNull(['PORTS']);Transformer.schema(schema).throwOnNull(keys) / .allowNull(keys)
Nested schema validation for object values.
config.select({
DATABASE: Transformer.schema({
HOST: 'string',
PORT: 'number',
}).throwOnNull(['HOST', 'PORT']),
}).throwOnNull(['DATABASE']);ConfigError
Thrown when a required property is null or invalid.
import { ConfigError } from '@debkit/schema';
try {
config.select({ MISSING: 'string' }).throwOnNull(['MISSING']);
} catch (e) {
if (e instanceof ConfigError) {
console.log(e.message); // 'Config property "MISSING" is invalid or missing'
}
}License
MIT
