import hyperid from 'hyperid'; const generateUniqueId = hyperid({ fixedLength: false, urlSafe: true }); export namespace BindingKey { /** * Create a new key for a binding bound to a value of type `ValueType`. * * @example * * ```ts * BindingKey.create('application.name'); * BindingKey.create('config#rest.port'); * ``` * * @param key - The binding key. When propertyPath is not provided, the key * is allowed to contain propertyPath as encoded via `BindingKey#toString()` * @public */ export function create(key: string): BindingAddress; /** * Create a new key for a binding bound to a value of type `ValueType`. * * @example * * ```ts * BindingKey.create('config', 'rest.port); * ``` * * @param key - The binding key. When propertyPath is not provided, the key * is allowed to contain propertyPath as encoded via `BindingKey#toString()` * @param propertyPath - Optional path to a deep property of the bound value. * @public */ /** * Create a new key for a binding bound to a value of type `ValueType`. * * @example * * ```ts * BindingKey.create('application.name'); * BindingKey.create('config', 'rest.port); * BindingKey.create('config#rest.port'); * ``` * * @param key - The binding key. When propertyPath is not provided, the key * is allowed to contain propertyPath as encoded via `BindingKey#toString()` * @param propertyPath - Optional path to a deep property of the bound value. * @public */ export function create(key: string, propertyPath: string): BindingAddress; export function create( key: string, propertyPath?: string ): BindingAddress { if (propertyPath) { key += '#' + propertyPath; } return key; } /** * Generate a universally unique binding key. * * Please note the format of they generated key is not specified, you must * not rely on any specific formatting (e.g. UUID style). * * @param namespace - Namespace for the binding * @public */ export function generate(namespace = ''): BindingAddress { const prefix = namespace ? `${namespace}.` : ''; const name = generateUniqueId(); return BindingKey.create(`${prefix}${name}`); } } declare const type: unique symbol; export type BindingAddress = | string | ({ [type]: T; } & string); export type AddressValue = T extends BindingAddress ? V : never;