@httpc/kit
Version:
httpc toolbox for building function-based API with minimal code and end-to-end type safety
62 lines (61 loc) • 2.19 kB
JavaScript
import assert from "assert";
import { inject, registry, container, injectWithTransform } from "tsyringe";
import { CONTAINER_KEY, KEY } from "./keys";
export function combine(...decorators) {
return function () {
for (const d of decorators) {
//@ts-ignore
d.apply(this, arguments);
}
};
}
export function noInject() {
return injectWithTransform(CONTAINER_KEY, NoInjectTransform);
}
class NoInjectTransform {
transform(container) {
return undefined;
}
}
export function alias(token) {
return (target) => registry([{ token, useFactory: container => container.resolve(target) }])(target);
}
export function initializer() {
return alias(KEY("IInitialize"));
}
export function env(variableName, defaultValue) {
const key = KEY("ENV", variableName);
const isOptional = arguments.length === 2;
if (!container.isRegistered(key)) {
container.register(key, {
useFactory: () => {
const value = process.env[variableName] ?? defaultValue;
if (typeof value === "undefined" && !isOptional) {
throw new Error(`Missing ENV variable '${variableName}'`);
}
return value;
}
});
}
return inject(key);
}
export function optionsOf(target) {
return alias(KEY("OPTIONS", target));
}
export function options(defaultValue) {
const isOptional = arguments.length === 1;
return (target, property, index) => {
assert(typeof target === "function", "options decorator must be used on a class constructor parameter");
const token = KEY("OPTIONS", target);
const decorator = isOptional ? optional(token, defaultValue) : inject(token);
return decorator(target, property, index);
};
}
export function optional(token, defaultValue) {
return injectWithTransform(CONTAINER_KEY, OptionalTransform, token, defaultValue);
}
class OptionalTransform {
transform(container, token, defaultValue) {
return container.isRegistered(token, true) ? container.resolve(token) : defaultValue;
}
}