UNPKG

@org-formation/tombok

Version:
67 lines (66 loc) 2.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.builder = void 0; /** * The builder decorator creates a so-called 'builder' aspect to the class that is annotated with `@builder`. * * Whenever a class is decorated, the private constructor is generated with all fields as arguments, * and it is as if this constructor has been decorated with `@builder` instead. * Note that this constructor is only generated if you haven't written any constructors and also haven't * added any explicit `@xArgsConstructor` decorators. In those cases, tombok will assume an all-args * constructor is present and generate code that uses it; this means you'd get a compiler error if this * constructor is not present. * * The effect of `@builder` is that an inner class is generated named `TBuilder`, * with a private constructor. Instances of `TBuilder` are made with the method named * `builder()` which is also generated for you in the class itself (not in the builder class). * * The `TBuilder` class contains 1 method for each parameter of the decorated class, which returns * the builder itself. The builder also has a `build()` method which returns a completed instance of * the original type, created by passing all parameters as set via the various other methods in the * builder to the constructor or method that was decorated with `@builder`. The return type of this * method will be the same as the relevant class, unless a method has been decorated, in which case * it'll be equal to the return type of that method. * * Example: * ```typescript * @builder * class Person {} * * Person.builder() * .name('Adam Savage').city('San Francisco') * .job('Mythbusters').job('Unchained Reaction') * .build(); * ``` * * @param <T> Type of the base class that must contain a constructor * @param {T} target Base class that we are going to mutate */ function builder(target) { return class TBuilder extends target { /** * Create a Builder for a class. Returned objects will be of the class type. * * @param <T> The class to instantiate. * @param {Partial<T>} [template] Class partial which the builder will derive initial params from. */ static builder(template) { const built = template ? Object.assign({}, template) : {}; const builder = new Proxy({}, { get(_, prop) { if ('build' === prop) { // Instantiate the input class with props const obj = new target(); return () => Object.assign(obj, { ...built }); } return (x) => { built[prop] = x; return builder; }; } }); return builder; } }; } exports.builder = builder;