export declare const NO_PROVIDER: unique symbol; export declare const DECLARATION_SEPARATOR = ">"; export declare const OPTIONAL_FLAG = "?"; export declare const ALLOWED_INITIALIZER_TYPES: readonly ["provider", "service", "constant"]; export type InitializerTypes = (typeof ALLOWED_INITIALIZER_TYPES)[number]; export type ServiceName = string; export type Service = any; export type Disposer = () => Promise; export type FatalErrorPromise = Promise; export interface Provider { service: S; dispose?: Disposer; fatalErrorPromise?: FatalErrorPromise; } export type Dependencies = Record; export type DependencyName = string; export type DependencyDeclaration = string; export interface LocationInformation { url: string; exportName: string; } export type ExtraInformation = any; export interface ParsedDependencyDeclaration { serviceName: string; mappedName: string; optional: boolean; } export interface ConstantProperties { $type: 'constant'; $name: DependencyName; $singleton: true; $location?: LocationInformation; } export type ConstantInitializer = ConstantProperties & { $value: S; }; export interface ProviderProperties { $type: 'provider'; $name: DependencyName; $inject?: DependencyDeclaration[]; $singleton?: boolean; $location?: LocationInformation; $extra?: ExtraInformation; } export interface ProviderInputProperties { type: 'provider'; name: DependencyName; inject?: DependencyDeclaration[]; singleton?: boolean; location?: LocationInformation; extra?: ExtraInformation; } export interface ProviderInitializerReqD extends ProviderProperties { (dependencies: D): Promise>; } export interface ProviderInitializerOptD extends ProviderProperties { (dependencies?: D): Promise>; } export type ProviderInitializer = ProviderInitializerReqD | ProviderInitializerOptD; export type ProviderInitializerBuilder = ((dependencies: D) => Promise>) | ((dependencies?: D) => Promise>); export interface ServiceProperties { $type: 'service'; $name: DependencyName; $inject?: DependencyDeclaration[]; $singleton?: boolean; $location?: LocationInformation; $extra?: ExtraInformation; } export interface ServiceInputProperties { type: 'service'; name: DependencyName; inject?: DependencyDeclaration[]; singleton?: boolean; location?: LocationInformation; extra?: ExtraInformation; } export interface ServiceInitializerReqD extends ServiceProperties { (dependencies: D): Promise; } export interface ServiceInitializerOptD extends ServiceProperties { (dependencies?: D): Promise; } export type ServiceInitializer = ServiceInitializerReqD | ServiceInitializerOptD; export type ServiceInitializerBuilder = ((dependencies: D) => Promise) | ((dependencies?: D) => Promise); export type InitializerProperties = ConstantProperties | ProviderProperties | ServiceProperties; export type InitializerBuilder = ProviderInitializerBuilder | ServiceInitializerBuilder | Partial> | Partial>; export type AsyncInitializer = ServiceInitializer | ProviderInitializer; export type Initializer = ConstantInitializer | ServiceInitializer | ProviderInitializer; export type ServiceInitializerWrapper = (dependencies: D, baseService: S) => Promise; export type ProviderInitializerWrapper = (dependencies: D, baseService: Provider) => Promise>; export declare const SPECIAL_PROPS_PREFIX = "$"; export declare const SPECIAL_PROPS: { readonly TYPE: "$type"; readonly NAME: "$name"; readonly INJECT: "$inject"; readonly SINGLETON: "$singleton"; readonly LOCATION: "$location"; readonly EXTRA: "$extra"; readonly VALUE: "$value"; }; export declare const ALLOWED_SPECIAL_PROPS: ("$type" | "$name" | "$inject" | "$singleton" | "$location" | "$extra" | "$value")[]; export type InitializerSpecialProp = (typeof ALLOWED_SPECIAL_PROPS)[number]; export declare function parseInjections(source: string, options?: { allowEmpty: boolean; }): DependencyDeclaration[]; export declare function readFunctionName(aFunction: Function): string; export declare function parseName(functionName: string): string; /** * Apply special props to the given initializer from another one * and optionally amend with new special props * @param {Function} from The initializer in which to pick the props * @param {Function} to The initializer from which to build the new one * @param {Object} [amend={}] Some properties to override * @return {Function} The newly built initializer */ export declare function reuseSpecialProps, TD extends Dependencies, S>(from: InitializerBuilder, to: ProviderInitializerBuilder, amend?: Partial): ProviderInitializerBuilder; export declare function reuseSpecialProps, TD extends Dependencies, S>(from: InitializerBuilder, to: ServiceInitializerBuilder, amend?: Partial): ServiceInitializerBuilder; /** * Decorator that creates an initializer for a constant value * @param {String} name * The constant's name. * @param {any} value * The constant's value * @return {Function} * Returns a new constant initializer * @example * import Knifecycle, { constant, service } from 'knifecycle'; * * const { printAnswer } = new Knifecycle() * .register(constant('THE_NUMBER', value)) * .register(constant('log', console.log.bind(console))) * .register(service( * async ({ THE_NUMBER, log }) => () => log(THE_NUMBER), * 'printAnswer', * ['THE_NUMBER', 'log'], * )) * .run(['printAnswer']); * * printAnswer(); // 42 */ export declare function constant(name: DependencyName, value: V): ConstantInitializer; /** * Decorator that creates an initializer from a service builder * @param {Function} serviceBuilder * An async function to build the service * @param {String} [name] * The service's name * @param {Array} [dependencies] * The service's injected dependencies * @param {Boolean} [singleton] * Whether the service is a singleton or not * @param {any} [extra] * Eventual extra information * @return {Function} * Returns a new initializer * @example * import Knifecycle, { constant, service } from 'knifecycle'; * * const { printAnswer } = new Knifecycle() * .register(constant('THE_NUMBER', value)) * .register(constant('log', console.log.bind(console))) * .register(service( * async ({ THE_NUMBER, log }) => () => log(THE_NUMBER), * 'printAnswer', * ['THE_NUMBER', 'log'], * true * )) * .run(['printAnswer']); * * printAnswer(); // 42 */ export declare function service, S>(serviceBuilder: ServiceInitializerBuilder, name?: DependencyName, dependencies?: DependencyDeclaration[], singleton?: boolean, extra?: ExtraInformation): ServiceInitializer; /** * Decorator that creates an initializer from a service * builder by automatically detecting its name * and dependencies * @param {Function} serviceBuilder * An async function to build the service * @return {Function} * Returns a new initializer */ export declare function autoService, S>(serviceBuilder: ServiceInitializerBuilder): ServiceInitializer; /** * Decorator that creates an initializer for a provider * builder * @param {Function} providerBuilder * An async function to build the service provider * @param {String} [name] * The service's name * @param {Array} [dependencies] * The service's dependencies * @param {Boolean} [singleton] * Whether the service is a singleton or not * @param {any} [extra] * Eventual extra information * @return {Function} * Returns a new provider initializer * @example * * import Knifecycle, { provider } from 'knifecycle' * import fs from 'fs'; * * const $ = new Knifecycle(); * * $.register(provider(configProvider, 'config')); * * async function configProvider() { * return new Promise((resolve, reject) { * fs.readFile('config.js', function(err, data) { * let config; * * if(err) { * reject(err); * return; * } * * try { * config = JSON.parse(data.toString); * } catch (err) { * reject(err); * return; * } * * resolve({ * service: config, * }); * }); * }); * } */ export declare function provider, S>(providerBuilder: ProviderInitializerBuilder, name?: DependencyName, dependencies?: DependencyDeclaration[], singleton?: boolean, extra?: ExtraInformation): ProviderInitializer; /** * Decorator that creates an initializer from a provider * builder by automatically detecting its name * and dependencies * @param {Function} providerBuilder * An async function to build the service provider * @return {Function} * Returns a new provider initializer */ export declare function autoProvider, S>(providerBuilder: ProviderInitializerBuilder): ProviderInitializer; /** * Allows to wrap an initializer to add extra initialization steps * @param {Function} wrapper * A function taking dependencies and the base * service in arguments * @param {Function} baseInitializer * The initializer to decorate * @return {Function} * The new initializer */ export declare function wrapInitializer, S>(wrapper: ProviderInitializerWrapper, baseInitializer: ProviderInitializer): ProviderInitializer; export declare function wrapInitializer, S>(wrapper: ServiceInitializerWrapper, baseInitializer: ServiceInitializer): ServiceInitializer; /** * Decorator creating a new initializer with different * dependencies declarations set to it. * @param {Array} dependencies * List of dependencies declarations to declare which * services the initializer needs to provide its * own service * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { inject } from 'knifecycle' * import myServiceInitializer from './service'; * * new Knifecycle() * .register( * service( * inject(['ENV'], myServiceInitializer) * 'myService', * ) * ) * ); */ export declare function inject, S>(dependencies: DependencyDeclaration[], initializer: ProviderInitializer): ProviderInitializer; export declare function inject, S>(dependencies: DependencyDeclaration[], initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function inject, S>(dependencies: DependencyDeclaration[], initializer: ServiceInitializer): ServiceInitializer; export declare function inject, S>(dependencies: DependencyDeclaration[], initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator creating a new initializer omitting * the given dependencies. * @param {Array} dependencies * List of dependencies to omit (also accept dependencies * declarations but omit the destination part) * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { unInject } from 'knifecycle' * import myServiceInitializer from './service'; * * new Knifecycle() * .register( * service( * unInject(['ENV'], myServiceInitializer) * 'myService', * ) * ) * ); */ export declare function unInject, S>(dependencies: DependencyDeclaration[], initializer: ProviderInitializer): ProviderInitializer; export declare function unInject, S>(dependencies: DependencyDeclaration[], initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function unInject, S>(dependencies: DependencyDeclaration[], initializer: ServiceInitializer): ServiceInitializer; export declare function unInject, S>(dependencies: DependencyDeclaration[], initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Apply injected dependencies from the given initializer to another one * @param {Function} from The initialization function in which to pick the dependencies * @param {Function} to The destination initialization function * @return {Function} The newly built initialization function */ export declare function useInject, S>(from: InitializerBuilder, to: ProviderInitializer): ProviderInitializer; export declare function useInject, S>(from: InitializerBuilder, to: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function useInject, S>(from: InitializerBuilder, to: ServiceInitializer): ServiceInitializer; export declare function useInject, S>(from: InitializerBuilder, to: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Merge injected dependencies of the given initializer with another one * @param {Function} from The initialization function in which to pick the dependencies * @param {Function} to The destination initialization function * @return {Function} The newly built initialization function */ export declare function mergeInject, D extends Dependencies, S>(from: InitializerBuilder, to: ProviderInitializer): ProviderInitializer; export declare function mergeInject, D extends Dependencies, S>(from: InitializerBuilder, to: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function mergeInject, D extends Dependencies, S>(from: InitializerBuilder, to: ServiceInitializer): ServiceInitializer; export declare function mergeInject, D extends Dependencies, S>(from: InitializerBuilder, to: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator creating a new initializer with different * dependencies declarations set to it according to the * given function signature. * @param {Function} initializer * The original initializer * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { autoInject, name } from 'knifecycle' * * new Knifecycle() * .register( * name( * 'application', * autoInject( * async ({ NODE_ENV, mysql: db }) => * async () => db.query('SELECT applicationId FROM applications WHERE environment=?', [NODE_ENV]) * ) * ) * ) * ) * ); */ export declare function autoInject, S>(initializer: ProviderInitializer): ProviderInitializer; export declare function autoInject, S>(initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function autoInject, S>(initializer: ServiceInitializer): ServiceInitializer; export declare function autoInject, S>(initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator creating a new initializer with some * more dependencies declarations appended to it. * @param {Array} dependencies * List of dependencies declarations to append * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { alsoInject } from 'knifecycle' * import myServiceInitializer from './service'; * * new Knifecycle() * .register(service( * alsoInject(['ENV'], myServiceInitializer), * 'myService', * )); */ export declare function alsoInject, D extends Dependencies, S>(dependencies: DependencyDeclaration[], to: ProviderInitializer): ProviderInitializer; export declare function alsoInject, D extends Dependencies, S>(dependencies: DependencyDeclaration[], to: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function alsoInject, D extends Dependencies, S>(dependencies: DependencyDeclaration[], to: ServiceInitializer): ServiceInitializer; export declare function alsoInject, D extends Dependencies, S>(dependencies: DependencyDeclaration[], to: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator creating a new initializer with some * extra information appended to it. It is just * a way for user to store some additional * information but has no interaction with the * Knifecycle internals. * @param {Object} extraInformation * An object containing those extra information. * @param {Function} initializer * The initializer to tweak * @param {Boolean} [merge=false] * Whether the extra object should be merged * with the existing one or not * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { extra } from 'knifecycle' * import myServiceInitializer from './service'; * * new Knifecycle() * .register(service( * extra({ httpHandler: true }, myServiceInitializer), * 'myService', * )); */ export declare function extra, S>(extraInformation: ExtraInformation, initializer: ProviderInitializer, merge?: boolean): ProviderInitializer; export declare function extra, S>(extraInformation: ExtraInformation, initializer: ProviderInitializerBuilder, merge?: boolean): ProviderInitializerBuilder; export declare function extra, S>(extraInformation: ExtraInformation, initializer: ServiceInitializer): ServiceInitializer; export declare function extra, S>(extraInformation: ExtraInformation, initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator to set an initializer singleton option. * @param {Function} initializer * The initializer to tweak * @param {boolean} [isSingleton=true] * Define the initializer singleton option * (one instance for several runs if true) * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { inject, singleton } from 'knifecycle'; * import myServiceInitializer from './service'; * * new Knifecycle() * .register(service( * inject(['ENV'], * singleton(myServiceInitializer) * ), * 'myService', * )); */ export declare function singleton, S>(initializer: ProviderInitializer, isSingleton?: boolean): ProviderInitializer; export declare function singleton, S>(initializer: ProviderInitializerBuilder, isSingleton?: boolean): ProviderInitializerBuilder; export declare function singleton, S>(initializer: ServiceInitializer, isSingleton?: boolean): ServiceInitializer; export declare function singleton, S>(initializer: ServiceInitializerBuilder, isSingleton?: boolean): ServiceInitializerBuilder; /** * Decorator to set an initializer location. * @param {Function} initializer * The initializer to tweak * @param {string} [url] * Define the initializer url (import.meta.url) in most situations * @param {string} [exportName] * Define the initializer export name * @return {Function} * Returns a new initializer * @example * * import { service, location } from 'knifecycle'; * * export const initMyService = location( * service(async () => {}, 'myService', []), * import.meta.url, * 'initMyService', * }); */ export declare function location, S>(initializer: ProviderInitializer, url: string, exportName?: string): ProviderInitializer; export declare function location, S>(initializer: ProviderInitializerBuilder, url: string, exportName?: string): ProviderInitializerBuilder; export declare function location, S>(initializer: ServiceInitializer, url: string, exportName?: string): ServiceInitializer; export declare function location, S>(initializer: ServiceInitializerBuilder, url: string, exportName?: string): ServiceInitializerBuilder; export declare function location, S>(initializer: ConstantInitializer, url: string, exportName?: string): ConstantInitializer; /** * Decorator to set an initializer name. * @param {String} name * The name of the service the initializer resolves to. * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer with that name set * @example * * import Knifecycle, { name } from 'knifecycle'; * import myServiceInitializer from './service'; * * new Knifecycle() * .register(name('myService', myServiceInitializer)); */ export declare function name, S>(name: DependencyName, initializer: ProviderInitializer): ProviderInitializer; export declare function name, S>(name: DependencyName, initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function name, S>(name: DependencyName, initializer: ServiceInitializer): ServiceInitializer; export declare function name, S>(name: DependencyName, initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator to set an initializer name from its function name. * @param {Function} initializer * The initializer to name * @return {Function} * Returns a new initializer with that name set * @example * * import Knifecycle, { autoName } from 'knifecycle'; * * new Knifecycle() * .register(autoName(async function myService() {})); */ export declare function autoName, S>(initializer: ProviderInitializer): ProviderInitializer; export declare function autoName, S>(initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function autoName, S>(initializer: ServiceInitializer): ServiceInitializer; export declare function autoName, S>(initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator to set an initializer type. * @param {String} type * The type to set to the initializer. * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { name, type } from 'knifecycle'; * import myServiceInitializer from './service'; * * new Knifecycle() * .register( * type('service', * name('myService', * myServiceInitializer * ) * ) * ); */ export declare function type, S>(type: 'provider', initializer: ProviderInitializer): ProviderInitializer; export declare function type, S>(type: 'provider', initializer: ProviderInitializerBuilder): ProviderInitializerBuilder; export declare function type, S>(type: 'service', initializer: ServiceInitializer): ServiceInitializer; export declare function type, S>(type: 'service', initializer: ServiceInitializerBuilder): ServiceInitializerBuilder; /** * Decorator to set an initializer properties. * @param {Object} properties * Properties to set to the service. * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns a new initializer * @example * * import Knifecycle, { initializer } from 'knifecycle'; * import myServiceInitializer from './service'; * * new Knifecycle() * .register(initializer({ * name: 'myService', * type: 'service', * inject: ['ENV'], * singleton: true, * }, myServiceInitializer)); */ export declare function initializer, S>(properties: ProviderInputProperties, initializer: ProviderInitializerBuilder): ProviderInitializer; export declare function initializer, S>(properties: ServiceInputProperties, initializer: ServiceInitializerBuilder): ServiceInitializer; /** * Explode a dependency declaration an returns its parts. * @param {String} dependencyDeclaration * A dependency declaration string * @return {Object} * The various parts of it * @example * parseDependencyDeclaration('pgsql>db'); * // Returns * { * serviceName: 'pgsql', * mappedName: 'db', * optional: false, * } */ export declare function parseDependencyDeclaration(dependencyDeclaration: DependencyDeclaration): ParsedDependencyDeclaration; /** * Stringify a dependency declaration from its parts. * @param {Object} dependencyDeclarationParts * A dependency declaration string * @return {String} * The various parts of it * @example * stringifyDependencyDeclaration({ * serviceName: 'pgsql', * mappedName: 'db', * optional: false, * }); * * // Returns * 'pgsql>db' */ export declare function stringifyDependencyDeclaration(dependencyDeclarationParts: ParsedDependencyDeclaration): DependencyDeclaration; /** * Utility function to check and reveal initializer properties. * @param {Function} initializer * The initializer to tweak * @return {Function} * Returns revealed initializer (with TypeScript types for properties) */ export declare function unwrapInitializerProperties>(initializer: ProviderInitializer): ProviderProperties; export declare function unwrapInitializerProperties>(initializer: ServiceInitializer): ServiceProperties; export declare function unwrapInitializerProperties>(initializer: ConstantInitializer): ConstantProperties; export declare function unwrapInitializerProperties>(initializer: Initializer): InitializerProperties; export declare function initializerBuilderIsOfType, S>(type: T, initializer: InitializerBuilder | ConstantInitializer): initializer is T extends 'service' ? ServiceInitializerBuilder : T extends 'provider' ? ServiceInitializerBuilder : ConstantInitializer; export declare function pickInitializerBuilderProp, S, T extends InitializerSpecialProp>(initializer: InitializerBuilder | ConstantInitializer, prop: T): T extends keyof ServiceProperties ? ServiceProperties[T] : S;