Skip to content

Types - Full Reference ​

Exhaustive reference for every utility type, resolver function, and constant class in @venizia/ignis-helpers, including the full HTTP and GRPC constant tables. For a readable introduction and the common tasks, start with the Types overview.

Files:

Find what you need ​

Looking forGo to
An escape hatch (any, a loose object)General Purpose Types
A value that may be absent, or a callback that may be asyncNullable and Promise Types
A constructor or class type parameterClass and Constructor Types
Telling a class from a plain function at runtimeisClass
Making object keys optional or required, or flattening A & BObject Utility Types
A union type derived from a const classConst Value Extraction Types
An option that accepts an eager value or a resolver functionValue Resolution Types and Functions
A config-driven field-to-type mappingField Mapping Types
DI container getter types, the configure() interfaceDI and Lifecycle Types
JSX component prop typesJSX Types
Query pagination defaults, the application nameDefaults
Detecting Bun vs Node at runtimeRuntimeModules
Schema data type constantsDataTypes
HTTP headers, methods, status codesHTTP
gRPC methods, headers, status codesGRPC
Content-type classification (image, video, text)MimeTypes
A file extension, a MIME content type, or the lookup between themContent types and file extensions
Reading '30d' into milliseconds, or converting between time unitsDuration
Keeping a secret out of a log lineRedaction

Import paths ​

typescript
// Types
import type {
  TNullable,
  AnyType,
  AnyObject,
  TOptions,
  ValueOrPromise,
  ValueOf,
  ValueOptional,
  ValueOptionalExcept,
  TPrettify,
  TConstructor,
  TAbstractConstructor,
  TClass,
  TAbstractClass,
  TMixinTarget,
  TAbstractMixinTarget,
  TResolver,
  TAsyncResolver,
  TValueOrResolver,
  TValueOrAsyncResolver,
  TStringConstValue,
  TNumberConstValue,
  TConstValue,
  TFieldMappingDataType,
  IFieldMapping,
  TFieldMappingNames,
  TObjectFromFieldMappings,
  TInjectionGetter,
  IConfigurable,
} from '@venizia/ignis-helpers';

// isClass (source-level class-syntax check, re-exported from @venizia/ignis-inversion)
import { isClass } from '@venizia/ignis-helpers';

// Resolver functions
import { resolveValue, resolveValueAsync, resolveClass } from '@venizia/ignis-helpers';

// Constants
import {
  Defaults,
  RuntimeModules,
  DataTypes,
  HTTP,
  GRPC,
  MimeTypes,
  FileExtensions,
  ContentTypes,
  ContentTypeTable,
  CONTENT_TYPE_BY_EXTENSION,
  DurationUnits,
  DurationAliases,
  DurationMultipliers,
} from '@venizia/ignis-helpers';

// Redaction
import { redactSecrets, toJsonSafe, redactUrlCredentials, REDACTED } from '@venizia/ignis-helpers';

// Derived constant types
import type {
  TRuntimeModule,
  TMimeTypes,
  TFileExtension,
  TContentType,
  TDurationUnit,
  IDuration,
  THttpMethod,
  THttpProtocol,
  THttpResultCode,
  TGrpcMethod,
  TGrpcResultCode,
} from '@venizia/ignis-helpers';

// JSX types (re-exported from hono/jsx)
import type { Child, FC, PropsWithChildren } from '@venizia/ignis-helpers';

All of the above resolve through the root @venizia/ignis-helpers barrel. It re-exports ./common in full, which includes ./common/types and ./common/constants.

General Purpose Types ​

Source -> types/utility.ts

typescript
type AnyType = any;
type AnyObject = Record<string | symbol | number, any>;
type TOptions<T extends object = {}> = T;
TypeMeaningUse
AnyTypeAlias for anyEscape hatch when a shape truly cannot be known at compile time
AnyObjectLoosely-typed recordObjects whose keys and value types are not known at compile time
TOptions<T>Identity wrapper around T (defaults to {})Semantic marker that a parameter follows the framework's options-object pattern

Nullable and Promise Types ​

Source -> types/utility.ts

typescript
type TNullable<T> = T | undefined | null;
type ValueOrPromise<T> = T | Promise<T>;
TypeMeaningUse
TNullable<T>T | undefined | nullA value that may be absent in either JavaScript "no value" form
ValueOrPromise<T>T | Promise<T>A method or callback that may be implemented sync or async

Class and Constructor Types ​

Source -> types/class.ts

typescript
type TConstructor<T> = new (...args: any[]) => T;
type TAbstractConstructor<T> = abstract new (...args: any[]) => T;
type TClass<T> = TConstructor<T> & { [property: string]: any };
type TAbstractClass<T> = TAbstractConstructor<T> & { [property: string]: any };
type TMixinTarget<T> = TConstructor<{ [P in keyof T]: T[P] }>;
type TAbstractMixinTarget<T> = TAbstractConstructor<{ [P in keyof T]: T[P] }>;
TypeMeaningUse
TConstructor<T>A concrete new (...args) => T constructorTyping a parameter that must be new-able
TAbstractConstructor<T>An abstract new (...args) => T constructorTyping a parameter that accepts an abstract class reference
TClass<T>TConstructor<T> plus an index signature for static membersThe most commonly used class type - a concrete class with arbitrary static properties
TAbstractClass<T>TAbstractConstructor<T> plus an index signature for static membersSame as TClass, for abstract classes
TMixinTarget<T>TConstructor over a mapped-identity copy of TTypes a mixin factory's Base parameter so the returned class keeps T's shape
TAbstractMixinTarget<T>TAbstractConstructor over a mapped-identity copy of TSame as TMixinTarget, for mixins over an abstract base
typescript
function MyMixin<T extends TMixinTarget<BaseClass>>(Base: T) {
  return class extends Base {
    // additional methods
  };
}

isClass ​

Source -> packages/inversion/src/common/utilities.ts

typescript
const isClass: <T>(target: any) => target is TClass<T>;

Declared in @venizia/ignis-inversion and re-exported by helpers. It's the single predicate that tells a constructor from a resolver function. Controller factories and resolveValue/resolveValueAsync/resolveClass all branch on it.

  • Filters to functions with a prototype - true of every non-arrow function, so this alone is not sufficient.
  • Decompiles the function via Function.prototype.toString and regex-tests that the source text literally starts with the class keyword.
  • Sound only when targeting ES2024+ - a class is emitted as class, never as an ES5 constructor function. Bundling this package down to ES5 breaks the predicate.

Object Utility Types ​

Source -> types/utility.ts

typescript
type ValueOf<T> = T[keyof T];
type ValueOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type ValueOptionalExcept<T, K extends keyof T> = Pick<T, K> & Partial<Omit<T, K>>;
type TPrettify<T> = { [K in keyof T]: T[K] } & {};
TypeMeaningUse
ValueOf<T>Union of all value types of TDeriving a union type from an object type, most often a const class
ValueOptional<T, K>T with keys K made optional, the rest unchangedRelaxing specific required fields
ValueOptionalExcept<T, K>T with everything optional except keys KThe inverse - only K stays required
TPrettify<T>Flattens an intersection (A & B) into one object typeReadable IDE hover tooltips when combining types with &

Const Value Extraction Types ​

Source -> types/const-value.ts

typescript
type TStringConstValue<T extends TClass<any>> = Extract<ValueOf<T>, string> & {};
type TNumberConstValue<T extends TClass<any>> = Extract<ValueOf<T>, number> & {};
type TConstValue<T extends TClass<any>> = Extract<ValueOf<T>, string | number> & {};

The & {} keeps the union literal: a value copied into an object literal, a let or an inferred generic stays 'node' | 'bun', not string.

TypeMeaningUse
TStringConstValue<T>The string-valued subset of ValueOf<T>Deriving a string union from a const class with mixed value types
TNumberConstValue<T>The number-valued subset of ValueOf<T>Deriving a numeric union from a const class with mixed value types
TConstValue<T>The string-or-number-valued subset of ValueOf<T>The common case - deriving a union type from a const class (RuntimeModules, MimeTypes)
typescript
type TRuntimeModule = TConstValue<typeof RuntimeModules>; // 'node' | 'bun'
type TMimeTypes = TConstValue<typeof MimeTypes>;          // 'unknown' | 'image' | 'video' | 'text'

Value Resolution Types and Functions ​

Types and functions for lazy/deferred value resolution - a core pattern in the framework's DI and configuration systems.

Types ​

Source -> types/resolver.ts

typescript
type TResolver<T> = (...args: any[]) => T;
type TAsyncResolver<T> = (...args: any[]) => T | Promise<T>;
type TValueOrResolver<T> = T | TResolver<T>;
type TValueOrAsyncResolver<T> = T | TAsyncResolver<T>;
TypeMeaningUse
TResolver<T>A sync function returning TDeferred value production
TAsyncResolver<T>A function returning T or Promise<T>Deferred value production that may be async
TValueOrResolver<T>T | TResolver<T>Config options that accept an eager value or a sync resolver
TValueOrAsyncResolver<T>T | TAsyncResolver<T>Config options that accept an eager value or a sync/async resolver

resolveValue ​

Source -> resolvers.ts (also resolveValueAsync, resolveClass)

typescript
const resolveValue: <T>(opts: { value: TValueOrResolver<T> }) => T;

Synchronously resolves a lazy value.

InputResult
Non-function valueReturned as-is
Class constructorReturned as-is - detected via isClass(), never invoked
Resolver functionInvoked; the return value is returned

resolveValueAsync ​

typescript
const resolveValueAsync: <T>(opts: { value: TValueOrAsyncResolver<T> }) => Promise<T>;

Async version of resolveValue. Same three cases, but the resolver's return value is await-ed before being returned.

resolveClass ​

typescript
const resolveClass: <T>(opts: {
  ref: TClass<T> | TResolver<TClass<T>> | string;
}) => TClass<T> | string;

Resolves lazy class references.

InputResult
String binding keyReturned as-is, for DI key lookups
Class constructorReturned as-is
Resolver functionInvoked via resolveValue; the result is returned

Resolution example ​

typescript
import { TValueOrAsyncResolver, resolveValueAsync } from '@venizia/ignis-helpers';

interface DatabaseConfig {
  host: string;
  port: number;
}

type ConfigOption = TValueOrAsyncResolver<DatabaseConfig>;

// Direct value
const config1: ConfigOption = { host: 'localhost', port: 5432 };

// Sync resolver
const config2: ConfigOption = () => ({ host: 'localhost', port: 5432 });

// Async resolver
const config3: ConfigOption = async () => {
  const config = await fetchConfigFromVault();
  return config;
};

// Resolve any of the above uniformly
const resolved = await resolveValueAsync({ value: config3 });

Field Mapping Types ​

Source -> types/field-mapping.ts

Types for declarative field-to-type mappings, used for configuration-driven data transformation.

typescript
type TFieldMappingDataType = 'string' | 'number' | 'strings' | 'numbers' | 'boolean';

interface IFieldMapping {
  name: string;
  type: TFieldMappingDataType;
  default?: string | number | Array<string> | Array<number> | boolean;
}

type TFieldMappingNames<T extends Array<IFieldMapping>> = Extract<
  T[number],
  { type: Exclude<T[number]['type'], undefined> }
>['name'];

type TObjectFromFieldMappings<
  T extends readonly {
    name: string;
    type: string;
    [extra: string | symbol]: any;
  }[],
> = {
  [K in T[number]['name']]: /* mapped to the declared type */
};
TypeMeaningUse
TFieldMappingDataTypeUnion of the five supported field kindsConstrains IFieldMapping.type
IFieldMapping{ name, type, default? }Declares one field's name, runtime type, and optional default
TFieldMappingNames<T>Union of name values from a field-mapping array typeExtracts the set of declared field names
TObjectFromFieldMappings<T>An object type keyed by T[number]['name']Maps each declared type to its runtime TypeScript equivalent: 'string' -> string, 'number' -> number, 'strings' -> string[], 'numbers' -> number[], 'boolean' -> boolean

DI and Lifecycle Types ​

Source -> types/injection.ts

typescript
type TInjectionGetter = <T>(opts: { key: string | symbol }) => T;

interface IConfigurable<Options extends object = any, Result = any> {
  configure(opts?: Options): ValueOrPromise<Result>;
}
TypeMeaningUse
TInjectionGetterA function retrieving T from the IoC container by binding keyTyping a container-getter parameter
IConfigurable<Options, Result>Interface with one configure(opts?) methodImplemented by helpers and components that expose an explicit initialization step

JSX Types ​

Source -> jsx.ts

Re-exported from hono/jsx for convenience when building JSX-based views:

typescript
export type { Child, FC, PropsWithChildren } from 'hono/jsx';
TypeMeaning
FCFunction component type
ChildValid child element type
PropsWithChildrenProps type that includes a children property

Constants ​

Defaults ​

Source -> constants/app.ts

typescript
class Defaults {
  static readonly APPLICATION_NAME: string; // process.env.APP_ENV_APPLICATION_NAME ?? 'APP'
  static readonly QUERY_LIMIT = 50;
  static readonly QUERY_OFFSET = 0;
}

Application-wide defaults for query pagination and application naming. APPLICATION_NAME is evaluated once, at module load.

RuntimeModules ​

typescript
class RuntimeModules {
  static readonly NODE = 'node';
  static readonly BUN = 'bun';

  static detect(): TRuntimeModule;
  static isBun(): boolean;
  static isNode(): boolean;
}

type TRuntimeModule = TConstValue<typeof RuntimeModules>; // 'node' | 'bun'

Runtime detection utility.

MethodBehavior
detect()Returns 'bun' if typeof Bun !== 'undefined', else 'node'
isBun()Calls detect() and compares to 'bun' - no caching, runs the check every time
isNode()Calls detect() and compares to 'node' - no caching, runs the check every time

DataTypes ​

typescript
class DataTypes {
  static readonly NUMBER = 'NUMBER';
  static readonly TEXT = 'TEXT';
  static readonly BYTE = 'BYTE';
  static readonly JSON = 'JSON';
  static readonly BOOLEAN = 'BOOLEAN';

  static readonly SCHEME_SET: Set<string>;
  static isValid(orgType: string): boolean;
}

Schema data type constants with validation. SCHEME_SET contains all five valid type strings, and isValid() checks membership.

HTTP ​

Source -> constants/http.ts

The HTTP class groups all HTTP-related constants into nested objects: Headers, HeaderValues, Methods, Protocols, and ResultCodes.

HTTP.Headers ​

Grouped by category, matching the source file's comments:

GroupConstantValue
ContentCONTENT_DISPOSITION'content-disposition'
CONTENT_ENCODING'content-encoding'
CONTENT_LENGTH'content-length'
CONTENT_TYPE'content-type'
CONTENT_RANGE'content-range'
CONTENT_SECURITY_POLICY'content-security-policy'
Request (content negotiation & conditionals)ACCEPT'accept'
ACCEPT_ENCODING'accept-encoding'
ACCEPT_LANGUAGE'accept-language'
AUTHORIZATION'authorization'
COOKIE'cookie'
HOST'host'
IF_MODIFIED_SINCE'if-modified-since'
IF_NONE_MATCH'if-none-match'
ORIGIN'origin'
REFERER'referer'
USER_AGENT'user-agent'
Response (caching, auth challenges & redirects)ALLOW'allow'
CACHE_CONTROL'cache-control'
ETAG'etag'
LAST_MODIFIED'last-modified'
LOCATION'location'
RETRY_AFTER'retry-after'
SET_COOKIE'set-cookie'
VARY'vary'
WWW_AUTHENTICATE'www-authenticate'
CORS (RFC 6454 / Fetch spec)ACCESS_CONTROL_ALLOW_CREDENTIALS'access-control-allow-credentials'
ACCESS_CONTROL_ALLOW_HEADERS'access-control-allow-headers'
ACCESS_CONTROL_ALLOW_METHODS'access-control-allow-methods'
ACCESS_CONTROL_ALLOW_ORIGIN'access-control-allow-origin'
ACCESS_CONTROL_EXPOSE_HEADERS'access-control-expose-headers'
ACCESS_CONTROL_MAX_AGE'access-control-max-age'
ACCESS_CONTROL_REQUEST_HEADERS'access-control-request-headers'
ACCESS_CONTROL_REQUEST_METHOD'access-control-request-method'
TransportCONNECTION'connection'
TRANSFER_ENCODING'transfer-encoding'
UPGRADE'upgrade'
SecuritySTRICT_TRANSPORT_SECURITY'strict-transport-security'
X_CONTENT_TYPE_OPTIONS'x-content-type-options'
X_FRAME_OPTIONS'x-frame-options'
Proxy / forwarding (de facto standard)FORWARDED'forwarded'
X_FORWARDED_FOR'x-forwarded-for'
X_FORWARDED_HOST'x-forwarded-host'
X_FORWARDED_PROTO'x-forwarded-proto'
Rate limiting (de facto standard)X_RATELIMIT_LIMIT'x-ratelimit-limit'
X_RATELIMIT_REMAINING'x-ratelimit-remaining'
X_RATELIMIT_RESET'x-ratelimit-reset'
IGNIS customREQUEST_TRACING_ID'x-request-id'
REQUEST_DEVICE_INFO'x-device-info'
REQUEST_CHANNEL'x-request-channel'
REQUEST_COUNT_DATA'x-request-count'
REQUEST_EXTRA'x-request-extra'
RESPONSE_COUNT_DATA'x-response-count'
RESPONSE_FORMAT'x-response-format'
RESPONSE_EXTRA'x-response-extra'

HTTP.CorsHeaders ​

The headers IGNIS adds, for a CORS configuration that lists headers by hand - spread them in, and a header IGNIS adds later needs no change there:

ConstantHeaders
ALLOWx-request-id, x-request-count, x-request-extra, x-request-channel, x-device-info
EXPOSEcontent-range, x-request-id, x-response-count, x-response-format, x-response-extra

HTTP.HeaderValues ​

GroupConstantValue
ApplicationAPPLICATION_FORM_URLENCODED'application/x-www-form-urlencoded'
APPLICATION_GRAPHQL_JSON'application/graphql+json'
APPLICATION_GZIP'application/gzip'
APPLICATION_JAVASCRIPT'application/javascript'
APPLICATION_JSON'application/json'
APPLICATION_MSGPACK'application/msgpack'
APPLICATION_NDJSON'application/x-ndjson'
APPLICATION_OCTET_STREAM'application/octet-stream'
APPLICATION_PDF'application/pdf'
APPLICATION_PROTOBUF'application/x-protobuf'
APPLICATION_XML'application/xml'
APPLICATION_ZIP'application/zip'
MultipartMULTIPART_FORM_DATA'multipart/form-data'
TextTEXT_CSS'text/css'
TEXT_CSV'text/csv'
TEXT_EVENT_STREAM'text/event-stream'
TEXT_HTML'text/html'
TEXT_PLAIN'text/plain'
TEXT_XML'text/xml'
ImageIMAGE_GIF'image/gif'
IMAGE_JPEG'image/jpeg'
IMAGE_PNG'image/png'
IMAGE_SVG'image/svg+xml'
IMAGE_WEBP'image/webp'

HTTP.Methods ​

ConstantValue
HTTP.Methods.GET'get'
HTTP.Methods.POST'post'
HTTP.Methods.PUT'put'
HTTP.Methods.PATCH'patch'
HTTP.Methods.DELETE'delete'
HTTP.Methods.HEAD'head'
HTTP.Methods.OPTIONS'options'
HTTP.Methods.QUERY'query' (RFC 10008 QUERY method)

IMPORTANT

All HTTP.Methods.* tokens are lowercase. @hono/zod-openapi route definitions accept no other case.

Every IGNIS network fetcher uppercases the method at the wire boundary, via method.toUpperCase(). But undici, Node's fetch implementation, only normalizes six of the eight methods on its own:

Undici normalizes it on its ownUndici does not
delete, get, head, options, post, putpatch, query

A lowercase patch or query sent as-is travels verbatim over Node, and the server rejects it. Bun's fetch uppercases every method, which hides the bug until the app runs on Node.

HTTP.Protocols ​

ConstantValue
HTTP.Protocols.HTTP'http'
HTTP.Protocols.HTTPS'https'

HTTP.ResultCodes ​

Status codes are grouped by class under HTTP.ResultCodes.RS_1 through HTTP.ResultCodes.RS_5 - for example, HTTP.ResultCodes.RS_4.NotFound.

GroupConstantValue
RS_1 (1xx)Continue100
SwitchingProtocols101
EarlyHints103
RS_2 (2xx)Ok200
Created201
Accepted202
NonAuthoritativeInformation203
NoContent204
ResetContent205
PartialContent206
MultiStatus207
RS_3 (3xx)MovedPermanently301
Found302
NotModified304
TemporaryRedirect307
PermanentRedirect308
RS_4 (4xx)BadRequest400
Unauthorized401
PaymentRequired402
Forbidden403
NotFound404
MethodNotAllowed405
NotAcceptable406
RequestTimeout408
Conflict409
Gone410
LengthRequired411
PreconditionFailed412
ContentTooLarge413
URITooLong414
UnsupportedMediaType415
RangeNotSatisfiable416
ExpectationFailed417
UnprocessableEntity422
Locked423
FailedDependency424
TooEarly425
UpgradeRequired426
PreconditionRequired428
TooManyRequests429
RequestHeaderFieldsTooLarge431
UnavailableForLegalReasons451
RS_5 (5xx)InternalServerError500
NotImplemented501
BadGateway502
ServiceUnavailable503
GatewayTimeout504
HTTPVersionNotSupported505
InsufficientStorage507
LoopDetected508
NetworkAuthenticationRequired511

Derived types ​

typescript
type THttpMethod = ValueOf<typeof HTTP.Methods> | Uppercase<ValueOf<typeof HTTP.Methods>>;
// 'get' | 'post' | ... | 'query' | 'GET' | 'POST' | ... | 'QUERY'

type THttpProtocol = ValueOf<typeof HTTP.Protocols> | Uppercase<ValueOf<typeof HTTP.Protocols>>;
// 'http' | 'https' | 'HTTP' | 'HTTPS'

type THttpResultCode = ValueOf<typeof HTTP.ResultCodes>;
// union of the RS_1..RS_5 group objects (not a flat number union)

GRPC ​

Source -> constants/grpc.ts

gRPC protocol constants for methods, headers, content types, and status codes.

PropertyTypeDescription
GRPC.Methods.UNARY'unary'Single request, single response
GRPC.Methods.SERVER_STREAMING'server_streaming'Single request, stream of responses
GRPC.Methods.CLIENT_STREAMING'client_streaming'Stream of requests, single response
GRPC.Methods.BIDI_STREAMING'bidi_streaming'Bidirectional streaming
GRPC.Headers.CONTENT_TYPE'content-type'HTTP content type header
GRPC.Headers.TE'te'Transfer encoding header
GRPC.Headers.USER_AGENT'user-agent'User agent header
GRPC.Headers.GRPC_TIMEOUT'grpc-timeout'gRPC timeout header
GRPC.Headers.GRPC_ENCODING'grpc-encoding'gRPC encoding header
GRPC.Headers.GRPC_ACCEPT_ENCODING'grpc-accept-encoding'gRPC accepted encodings header
GRPC.Headers.GRPC_MESSAGE_TYPE'grpc-message-type'gRPC message type header
GRPC.Headers.GRPC_STATUS'grpc-status'gRPC status code header
GRPC.Headers.GRPC_MESSAGE'grpc-message'gRPC error message header
GRPC.Headers.GRPC_STATUS_DETAILS_BIN'grpc-status-details-bin'gRPC binary status details header
GRPC.Headers.GRPC_PREVIOUS_RPC_ATTEMPTS'grpc-previous-rpc-attempts'gRPC previous RPC attempts header
GRPC.Headers.GRPC_RETRY_PUSHBACK_MS'grpc-retry-pushback-ms'gRPC retry pushback milliseconds header
GRPC.Headers.GRPC_TRACE_BIN'grpc-trace-bin'gRPC binary trace context header
GRPC.Headers.GRPC_TAGS_BIN'grpc-tags-bin'gRPC binary tags header
GRPC.HeaderValues.GRPC'application/grpc'Standard gRPC content type
GRPC.HeaderValues.GRPC_PROTO'application/grpc+proto'gRPC Protobuf content type
GRPC.HeaderValues.GRPC_JSON'application/grpc+json'gRPC JSON content type
GRPC.HeaderValues.GRPC_WEB'application/grpc-web'gRPC-Web content type
GRPC.HeaderValues.GRPC_WEB_PROTO'application/grpc-web+proto'gRPC-Web Protobuf content type
GRPC.HeaderValues.GRPC_WEB_JSON'application/grpc-web+json'gRPC-Web JSON content type
GRPC.HeaderValues.GRPC_WEB_TEXT'application/grpc-web-text'gRPC-Web text content type
GRPC.ResultCodes.OK0Success
GRPC.ResultCodes.CANCELLED1Operation cancelled
GRPC.ResultCodes.UNKNOWN2Unknown error
GRPC.ResultCodes.INVALID_ARGUMENT3Invalid argument
GRPC.ResultCodes.DEADLINE_EXCEEDED4Deadline exceeded
GRPC.ResultCodes.NOT_FOUND5Not found
GRPC.ResultCodes.ALREADY_EXISTS6Already exists
GRPC.ResultCodes.PERMISSION_DENIED7Permission denied
GRPC.ResultCodes.RESOURCE_EXHAUSTED8Resource exhausted
GRPC.ResultCodes.FAILED_PRECONDITION9Failed precondition
GRPC.ResultCodes.ABORTED10Operation aborted
GRPC.ResultCodes.OUT_OF_RANGE11Out of range
GRPC.ResultCodes.UNIMPLEMENTED12Unimplemented
GRPC.ResultCodes.INTERNAL13Internal server error
GRPC.ResultCodes.UNAVAILABLE14Service unavailable
GRPC.ResultCodes.DATA_LOSS15Unrecoverable data loss
GRPC.ResultCodes.UNAUTHENTICATED16Unauthenticated
typescript
type TGrpcMethod = ValueOf<typeof GRPC.Methods>;
type TGrpcResultCode = ValueOf<typeof GRPC.ResultCodes>;

MimeTypes ​

Source -> constants/mime.ts

typescript
class MimeTypes {
  static readonly UNKNOWN = 'unknown';
  static readonly IMAGE = 'image';
  static readonly VIDEO = 'video';
  static readonly TEXT = 'text';
}

type TMimeTypes = TConstValue<typeof MimeTypes>; // 'unknown' | 'image' | 'video' | 'text'

Content type classification constants. MimeTypes.isValid(value) returns true for one of the four.

Content types and file extensions ​

Source -> constants/mime.ts

The same file carries three more const classes, for the concrete extension and MIME strings.

Const classDerived typeHolds
FileExtensionsTFileExtension19 lowercase extensions, leading dot included - '.png', '.mp4', '.xml'. The dot is part of the value, because path.extname returns one
ContentTypesTContentType19 MIME strings - 'image/png', 'application/json', plus OCTET_STREAM as the fallback
ContentTypeTable-BY_EXTENSION, the extension-to-content-type map, and resolve() over it
typescript
import { ContentTypeTable, ContentTypes, FileExtensions } from '@venizia/ignis-helpers';

ContentTypeTable.resolve({ filename: 'report.PDF' }); // 'application/pdf' - the match is case-insensitive
ContentTypeTable.resolve({ filename: 'archive.bin' }); // 'application/octet-stream' - the fallback
ContentTypeTable.resolve({ filename: 'LICENSE' });     // 'application/octet-stream' - no extension

FileExtensions.isValid('.webp');   // true
ContentTypes.isValid('image/png'); // true

resolve() never throws and never returns undefined. An unknown or absent extension yields ContentTypes.OCTET_STREAM.

CONTENT_TYPE_BY_EXTENSION is exported as a one-line delegate to ContentTypeTable.BY_EXTENSION, kept for callers that predate the table moving onto the class.

ContentTypeTable does not use node:path. The file is reachable from the browser-pure ./common subpath, and an extension is the tail after the last dot either way.

Duration ​

Source -> constants/duration.ts

typescript
class DurationUnits {
  static readonly MILLISECOND = 'millisecond';
  static readonly SECOND = 'second';
  static readonly MINUTE = 'minute';
  static readonly HOUR = 'hour';
  static readonly DAY = 'day';
  static readonly WEEK = 'week';
  static readonly MONTH = 'month';
  static readonly YEAR = 'year';
}

type TDurationUnit = TConstValue<typeof DurationUnits>;

interface IDuration {
  unit: TDurationUnit;
  value: number;
}

DurationAliases maps written spellings onto those units. DurationAliases.resolve(input) returns the canonical unit, or null.

UnitSpellings
millisecondms, msec, millisecond, milliseconds
seconds, sec, second, seconds
minutem, min, minute, minutes
hourh, hr, hour, hours
dayd, day, days
weekw, wk, week, weeks
monthmo, mon, month, months
yeary, yr, year, years

WARNING

m is minute and mo is month. There is no single-letter month. This is the one ambiguity readers trip on, and it matches what every duration library does.

DurationMultipliers does the arithmetic. Every method answers null rather than throwing, so a caller raises its own error with its own context.

MethodSignatureReturns
parse(input: string): IDuration | null'30d', '1500 ms', '-2 Hours' read into { unit, value }
parseToMilliseconds(input: string): number | nullparse straight to milliseconds
toMilliseconds(opts: IDuration | null): number | nullRounded to a whole millisecond
fromMilliseconds(opts: { milliseconds: number; unit: TDurationUnit }): number | nullFractional on purpose
convert(opts: { value: number; from: TDurationUnit; to: TDurationUnit }): number | nullUnit to unit, through milliseconds
typescript
import { DurationMultipliers } from '@venizia/ignis-helpers';

DurationMultipliers.parseToMilliseconds('30d');   // 2592000000
DurationMultipliers.parse('2 hours');             // { unit: 'hour', value: 2 }
DurationMultipliers.parseToMilliseconds('30 xy'); // null
DurationMultipliers.convert({ value: 36, from: 'hour', to: 'day' }); // 1.5

WARNING

A month is 30 days and a year is 365, nominal. These size a window - a grace period, a cache TTL, a near-expiry horizon. Never use them to compute a calendar date. Adding one month to 31 January lands on 2 March in a leap year and 3 March otherwise. Use a date library for calendar arithmetic.

Redaction ​

Source -> common/redact.ts

Keeps secrets out of log lines. Key names are matched case-insensitively, at any depth.

ExportSignatureDoes
redactSecrets(value: unknown, seen?: WeakSet<object>, depth?: number): unknownReplaces the value of any secret-looking key with REDACTED. depth defaults to Infinity
toJsonSafe(opts: { value: unknown; depth?: number }): unknownProjects a value into something JSON.stringify can render, breaking cycles per branch
redactUrlCredentials(url: string): stringStrips the password out of a connection URL's authority section
REDACTED'[REDACTED]'The replacement string

The key pattern covers the options spellings (password, secret, apiKey, privateKey, connectionString), the snake_case wire spellings (client_token, secret_id, role_id), any *_token/*Token and *_secret/*Secret key, and the HTTP header spellings (x-api-key, authorization, cookie, set-cookie).

redactUrlCredentials exists because redactSecrets matches on key names and cannot see a password sitting inside a URL string. A value that does not parse as a URL comes back unchanged.

typescript
import { redactSecrets, redactUrlCredentials, toJsonSafe } from '@venizia/ignis-helpers';

redactSecrets({ user: 'ada', password: 'hunter2' });
// => { user: 'ada', password: '[REDACTED]' }

redactUrlCredentials('postgres://ada:hunter2@db:5432/app');
// => 'postgres://ada:[REDACTED]@db:5432/app'

const node: Record<string, unknown> = { name: 'a' };
node.self = node;
toJsonSafe({ value: node });
// => { name: 'a', self: '[Circular]' } - one branch, not the whole payload

WARNING

APP_ENV_LOGGER_DO_REDACT=false turns key masking off, for local debugging only. It is fail-closed: only the literal string false disables it, and it is read per call. The structural pass in toJsonSafe always runs regardless.

See also ​