// Utility types /** * @internal Base type for all `methods`-like metadata. * @template This The type to use for `this` within methods. */ interface MethodMap { [s: string]: ((this: This, ...args: any[]) => any) | {}; } /** @internal A plain old JavaScript object created by a `Stamp`. */ type Pojo = object; // { [s: string]: any; } /** @internal Base type for all `properties`-like metadata. */ // TODO: discriminate Array type PropertyMap = object; // { [s: string]: any; } /** @internal Signature common to every `Stamp`s. */ interface StampSignature { (options?: PropertyMap, ...args: unknown[]): any; compose: ComposeMethod & stampit.Descriptor; } /** * @internal Extracts the `Stamp` type. * @template Original The type to extract the `Stamp` type from. */ type StampType = Original extends /* disallowed types */ [] | bigint ? never : stampit.IsADescriptor extends true ? (Original extends stampit.ExtendedDescriptor ? Stamp : never) : unknown extends Original /* is any or unknown */ ? stampit.Stamp : Original extends StampSignature ? Original : Original extends stampit.ExtendedDescriptor ? stampit.Stamp : Original extends Pojo ? stampit.Stamp /*assume it is the object from a stamp object*/ : never; /** * @internal The type of the object produced by the `Stamp`. * @template Original The type (either a `Stamp` or a `ExtendedDescriptor`) to get the object type from. */ type StampObjectType = Original extends /* disallowed types */ bigint | boolean | number | string | symbol ? never : stampit.IsADescriptor extends true ? (Original extends stampit.ExtendedDescriptor ? Obj : never) : unknown extends Original /* is any or unknown */ ? Original : Original extends StampSignature ? (Original extends stampit.Stamp /* extended stamps may require infering twice */ ? (Obj extends stampit.Stamp ? Obj : Obj) : any) : Original extends stampit.ExtendedDescriptor ? Obj : Original extends Pojo ? Original : never; /** * A factory function to create plain object instances. * @template Obj The object type that the `Stamp` will create. */ interface FactoryFunction { (options?: PropertyMap, ...args: any[]): StampObjectType; } /** * @internal Chainables `Stamp` additionnal methods * @template Obj The object type that the `Stamp` will create. */ type StampChainables = Chainables, StampType>; /** * @internal Chainables `Stamp` additionnal methods * @template Obj The object type that the `Stamp` will create. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` (when extending a `Stamp`.) */ interface Chainables { /** * Add methods to the methods prototype. Creates and returns new Stamp. **Chainable**. * @template This The type to use for `this` within methods. * @param methods Object(s) containing map of method names and bodies for delegation. */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics methods(...methods: Array>): S̤t̤a̤m̤p̤; /** * Take a variable number of objects and shallow assign them to any future created instance of the Stamp. Creates and returns new Stamp. **Chainable**. * @param objects Object(s) to shallow assign for each new object. */ properties(...objects: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take a variable number of objects and shallow assign them to any future created instance of the Stamp. Creates and returns new Stamp. **Chainable**. * @param objects Object(s) to shallow assign for each new object. */ props(...objects: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take a variable number of objects and deeply merge them to any future created instance of the Stamp. Creates and returns a new Stamp. **Chainable**. * @param deepObjects The object(s) to deeply merge for each new object. */ deepProperties(...deepObjects: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take a variable number of objects and deeply merge them to any future created instance of the Stamp. Creates and returns a new Stamp. **Chainable**. * @param deepObjects The object(s) to deeply merge for each new object. */ deepProps(...deepObjects: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take in a variable number of functions and add them to the initializers prototype as initializers. **Chainable**. * @param functions Initializer functions used to create private data and privileged methods. */ initializers(...functions: Array>): S̤t̤a̤m̤p̤; initializers(functions: Array>): S̤t̤a̤m̤p̤; /** * Take in a variable number of functions and add them to the initializers prototype as initializers. **Chainable**. * @param functions Initializer functions used to create private data and privileged methods. */ init(...functions: Array>): S̤t̤a̤m̤p̤; init(functions: Array>): S̤t̤a̤m̤p̤; /** * Take n objects and add them to a new stamp and any future stamp it composes with. Creates and returns new Stamp. **Chainable**. * @param statics Object(s) containing map of property names and values to mixin into each new stamp. */ staticProperties(...statics: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take n objects and add them to a new stamp and any future stamp it composes with. Creates and returns new Stamp. **Chainable**. * @param statics Object(s) containing map of property names and values to mixin into each new stamp. */ statics(...statics: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Deeply merge a variable number of objects and add them to a new stamp and any future stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param deepStatics The object(s) containing static properties to be merged. */ staticDeepProperties(...deepStatics: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Deeply merge a variable number of objects and add them to a new stamp and any future stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param deepStatics The object(s) containing static properties to be merged. */ deepStatics(...deepStatics: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Take in a variable number of functions and add them to the composers prototype as composers. **Chainable**. * @param functions Composer functions that will run in sequence while creating a new stamp from a list of composables. The resulting stamp and the composables get passed to composers. */ composers(...functions: Array>): S̤t̤a̤m̤p̤; composers(functions: Array>): S̤t̤a̤m̤p̤; /** * Shallowly assign properties of Stamp arbitrary metadata and add them to a new stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param confs The object(s) containing metadata properties. */ configuration(...confs: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Shallowly assign properties of Stamp arbitrary metadata and add them to a new stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param confs The object(s) containing metadata properties. */ conf(...confs: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Deeply merge properties of Stamp arbitrary metadata and add them to a new Stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param deepConfs The object(s) containing metadata properties. */ deepConfiguration(...deepConfs: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Deeply merge properties of Stamp arbitrary metadata and add them to a new Stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @param deepConfs The object(s) containing metadata properties. */ deepConf(...deepConfs: PropertyMap[]): S̤t̤a̤m̤p̤; /** * Apply ES5 property descriptors to object instances created by the new Stamp returned by the function and any future Stamp it composes. Creates and returns a new stamp. **Chainable**. * @param descriptors */ propertyDescriptors(...descriptors: PropertyDescriptorMap[]): S̤t̤a̤m̤p̤; /** * Apply ES5 property descriptors to a Stamp and any future Stamp it composes. Creates and returns a new stamp. **Chainable**. * @param descriptors */ staticPropertyDescriptors(...descriptors: PropertyDescriptorMap[]): S̤t̤a̤m̤p̤; } /** * A function which creates a new `Stamp`s from a list of `Composable`s. * @template Obj The type of the object instance being produced by the `Stamp` or the type of the `Stamp` being created (when extending a `Stamp`.) */ type ComposeMethod = typeof stampit; /** * A function which creates a new `Stamp`s from a list of `Composable`s. * @template Obj The type of the object instance being created by the `Stamp` or the type of the `Stamp` being created (when extending a `Stamp`.) */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics declare function stampit(...composables: stampit.Composable[]): StampType; declare namespace stampit { /** A composable object (either a `Stamp` or a `ExtendedDescriptor`.) */ type Composable = StampSignature | ExtendedDescriptor; /** * A `Stamp`'s metadata. * @template Obj The type of the object instance being produced by the `Stamp`. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` (when extending a `Stamp`.) */ interface Descriptor> { /** A set of methods that will be added to the object's delegate prototype. */ methods?: MethodMap | undefined; /** A set of properties that will be added to new object instances by assignment. */ properties?: PropertyMap | undefined; /** A set of properties that will be added to new object instances by deep property merge. */ deepProperties?: PropertyMap | undefined; /** A set of object property descriptors (`PropertyDescriptor`) used for fine-grained control over object property behaviors. */ propertyDescriptors?: PropertyDescriptorMap | undefined; /** A set of static properties that will be copied by assignment to the `Stamp`. */ staticProperties?: PropertyMap | undefined /* & ThisType */; /** A set of static properties that will be added to the `Stamp` by deep property merge. */ staticDeepProperties?: PropertyMap | undefined /* & ThisType */; /** A set of object property descriptors (`PropertyDescriptor`) to apply to the `Stamp`. */ staticPropertyDescriptors?: PropertyDescriptorMap | undefined /* & ThisType */; /** An array of functions that will run in sequence while creating an object instance from a `Stamp`. `Stamp` details and arguments get passed to initializers. */ initializers?: Initializer | Array> | undefined; /** An array of functions that will run in sequence while creating a new `Stamp` from a list of `Composable`s. The resulting `Stamp` and the `Composable`s get passed to composers. */ composers?: Array> | undefined; /** A set of options made available to the `Stamp` and its initializers during object instance creation. These will be copied by assignment. */ configuration?: PropertyMap | undefined /* & ThisType */; /** A set of options made available to the `Stamp` and its initializers during object instance creation. These will be deep merged. */ deepConfiguration?: PropertyMap | undefined /* & ThisType */; } /** * A `stampit`'s metadata. * @template Obj The type of the object instance being produced by the `Stamp`. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` (when extending a `Stamp`.) */ interface ExtendedDescriptor> extends Descriptor { /** A set of properties that will be added to new object instances by assignment. */ props?: PropertyMap | undefined; /** A set of properties that will be added to new object instances by deep property merge. */ deepProps?: PropertyMap | undefined; /** A set of static properties that will be copied by assignment to the `Stamp`. */ statics?: PropertyMap | undefined /* & ThisType */; /** A set of static properties that will be added to the `Stamp` by deep property merge. */ deepStatics?: PropertyMap | undefined /* & ThisType */; /** An array of functions that will run in sequence while creating an object instance from a `Stamp`. `Stamp` details and arguments get passed to initializers. */ init?: Initializer | Array> | undefined; /** A set of options made available to the `Stamp` and its initializers during object instance creation. These will be copied by assignment. */ conf?: PropertyMap | undefined /* & ThisType */; /** A set of options made available to the `Stamp` and its initializers during object instance creation. These will be deep merged. */ deepConf?: PropertyMap | undefined /* & ThisType */; // TODO: Add description name?: string | undefined; } /** * @internal Checks that a type is a ExtendedDescriptor (except `any` and `unknown`). * @template Type A type to check if a ExtendedDescriptor. */ // TODO: Improve test by checking the type of common keys type IsADescriptor = unknown extends Type ? (keyof Type extends never ? false : keyof Type extends infer K ? (K extends keyof ExtendedDescriptor ? true : false) : false) : false; /** * A function used as `.initializers` argument. * @template Obj The type of the object instance being produced by the `Stamp`. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` producing the instance. */ interface Initializer { // eslint-disable-next-line @typescript-eslint/no-invalid-void-type (this: Obj, options: /*_propertyMap*/ any, context: InitializerContext): void | Obj; } /** * The `Initializer` function context. * @template Obj The type of the object instance being produced by the `Stamp`. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` producing the instance. */ interface InitializerContext { /** The object instance being produced by the `Stamp`. If the initializer returns a value other than `undefined`, it replaces the instance. */ instance: Obj; /** A reference to the `Stamp` producing the instance. */ stamp: S̤t̤a̤m̤p̤; /** An array of the arguments passed into the `Stamp`, including the options argument. */ // ! above description from the specification is obscure args: any[]; } /** * A function used as `.composers` argument. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` produced by the `.compose()` method. */ interface Composer { // eslint-disable-next-line @typescript-eslint/no-invalid-void-type (parameters: ComposerParameters): void | S̤t̤a̤m̤p̤; } /** * The parameters received by the current `.composers` function. * @template S̤t̤a̤m̤p̤ The type of the `Stamp` produced by the `.compose()` method. */ interface ComposerParameters { /** The result of the `Composable`s composition. */ stamp: S̤t̤a̤m̤p̤; /** The list of composables the `Stamp` was just composed of. */ composables: Composable[]; } /** * A factory function to create plain object instances. * * It also has a `.compose()` method which is a copy of the `ComposeMethod` function and a `.compose` accessor to its `Descriptor`. * @template Obj The object type that the `Stamp` will create. */ interface Stamp extends FactoryFunction, StampChainables, StampSignature { /** Just like calling stamp(), stamp.create() invokes the stamp and returns a new instance. */ create: FactoryFunction; /** * A function which creates a new `Stamp`s from a list of `Composable`s. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. */ compose: ComposeMethod & Descriptor>; } /** * A shortcut method for stampit().methods() * * Add methods to the methods prototype. Creates and returns new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @template This The type to use for `this` within methods. * @param methods Object(s) containing map of method names and bodies for delegation. */ function methods(this: StampObjectType, ...methods: Array>): StampType; /** * A shortcut method for stampit().properties() * * Take a variable number of objects and shallow assign them to any future created instance of the Stamp. Creates and returns new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param objects Object(s) to shallow assign for each new object. */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function properties(...objects: PropertyMap[]): StampType; /** * A shortcut method for stampit().props() * * Take a variable number of objects and shallow assign them to any future created instance of the Stamp. Creates and returns new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param objects Object(s) to shallow assign for each new object. */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function props(...objects: PropertyMap[]): StampType; /** * A shortcut method for stampit().deepProperties() * * Take a variable number of objects and deeply merge them to any future created instance of the Stamp. Creates and returns a new Stamp. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepObjects The object(s) to deeply merge for each new object */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function deepProperties(...deepObjects: PropertyMap[]): StampType; /** * A shortcut method for stampit().deepProps() * * Take a variable number of objects and deeply merge them to any future created instance of the Stamp. Creates and returns a new Stamp. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepObjects The object(s) to deeply merge for each new object */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function deepProps(...deepObjects: PropertyMap[]): StampType; /** * A shortcut method for stampit().initializers() * * Take in a variable number of functions and add them to the initializers prototype as initializers. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param functions Initializer functions used to create private data and privileged methods */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function initializers>( ...functions: Array, S̤t̤a̤m̤p̤>> ): S̤t̤a̤m̤p̤; // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function initializers>( functions: Array, S̤t̤a̤m̤p̤>>, ): S̤t̤a̤m̤p̤; /** * A shortcut method for stampit().init() * * Take in a variable number of functions and add them to the initializers prototype as initializers. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param functions Initializer functions used to create private data and privileged methods */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function init>( ...functions: Array, S̤t̤a̤m̤p̤>> ): S̤t̤a̤m̤p̤; // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function init>( functions: Array, S̤t̤a̤m̤p̤>>, ): S̤t̤a̤m̤p̤; /** * A shortcut method for stampit().statics() * * Take n objects and add them to a new stamp and any future stamp it composes with. Creates and returns new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param statics Object(s) containing map of property names and values to mixin into each new stamp. */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function staticProperties(...statics: PropertyMap[]): StampType; /** * A shortcut method for stampit().staticProperties() * * Take n objects and add them to a new stamp and any future stamp it composes with. Creates and returns new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param statics Object(s) containing map of property names and values to mixin into each new stamp. */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function statics(...statics: PropertyMap[]): StampType; /** * A shortcut method for stampit().staticDeepProperties() * * Deeply merge a variable number of objects and add them to a new stamp and any future stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepStatics The object(s) containing static properties to be merged */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function staticDeepProperties(...deepStatics: PropertyMap[]): StampType; /** * A shortcut method for stampit().deepStatics() * * Deeply merge a variable number of objects and add them to a new stamp and any future stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepStatics The object(s) containing static properties to be merged */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function deepStatics(...deepStatics: PropertyMap[]): StampType; /** * A shortcut method for stampit().composers() * * Take in a variable number of functions and add them to the composers prototype as composers. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param functions Composer functions that will run in sequence while creating a new stamp from a list of composables. The resulting stamp and the composables get passed to composers. */ function composers(...functions: Array>>): StampType; function composers(functions: Array>>): StampType; /** * A shortcut method for stampit().configuration() * * Shallowly assign properties of Stamp arbitrary metadata and add them to a new stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param confs The object(s) containing metadata properties */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function configuration(...confs: PropertyMap[]): StampType; /** * A shortcut method for stampit().conf() * * Shallowly assign properties of Stamp arbitrary metadata and add them to a new stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param confs The object(s) containing metadata properties */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function conf(...confs: PropertyMap[]): StampType; /** * A shortcut method for stampit().deepConfiguration() * * Deeply merge properties of Stamp arbitrary metadata and add them to a new Stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepConfs The object(s) containing metadata properties */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function deepConfiguration(...deepConfs: PropertyMap[]): StampType; /** * A shortcut method for stampit().deepConf() * * Deeply merge properties of Stamp arbitrary metadata and add them to a new Stamp and any future Stamp it composes. Creates and returns a new Stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param deepConfs The object(s) containing metadata properties */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function deepConf(...deepConfs: PropertyMap[]): StampType; /** * A shortcut method for stampit().propertyDescriptors() * * Apply ES5 property descriptors to object instances created by the new Stamp returned by the function and any future Stamp it composes. Creates and returns a new stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param descriptors */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function propertyDescriptors(...descriptors: PropertyDescriptorMap[]): StampType; /** * A shortcut method for stampit().staticPropertyDescriptors() * * Apply ES5 property descriptors to a Stamp and any future Stamp it composes. Creates and returns a new stamp. **Chainable**. * @template Obj The type of the object instance being produced by the `Stamp`. or the type of the `Stamp` being created. * @param descriptors */ // eslint-disable-next-line @definitelytyped/no-unnecessary-generics function staticPropertyDescriptors(...descriptors: PropertyDescriptorMap[]): StampType; /** A function which creates a new `Stamp`s from a list of `Composable`s. */ const compose: ComposeMethod; /** the version of the NPM `stampit` package. */ const version: string; } export const compose: typeof stampit.compose; export const composers: typeof stampit.composers; export const conf: typeof stampit.conf; export const configuration: typeof stampit.configuration; export const deepConf: typeof stampit.deepConf; export const deepConfiguration: typeof stampit.deepConfiguration; export const deepProperties: typeof stampit.deepProperties; export const deepProps: typeof stampit.deepProps; export const deepStatics: typeof stampit.deepStatics; export const init: typeof stampit.init; export const initializers: typeof stampit.initializers; export const methods: typeof stampit.methods; export const properties: typeof stampit.properties; export const propertyDescriptors: typeof stampit.propertyDescriptors; export const props: typeof stampit.props; export const staticDeepProperties: typeof stampit.staticDeepProperties; export const staticProperties: typeof stampit.staticProperties; export const staticPropertyDescriptors: typeof stampit.staticPropertyDescriptors; export const version: typeof stampit.version; export default stampit;