UNPKG

@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
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; } }