{"version":3,"sources":["../src/Builder.ts","../src/StrictBuilder.ts"],"sourcesContent":["export type IBuilder<T> = {\r\n  [k in keyof T]-?: ((arg: T[k]) => IBuilder<T>) & (() => T[k]);\r\n}\r\n& {\r\n  build(): T;\r\n};\r\n\r\ntype Clazz<T> = new(...args: unknown[]) => T;\r\n\r\n/**\r\n * Create a Builder for a class. Returned objects will be of the class type.\r\n *\r\n * e.g. let obj: MyClass = Builder(MyClass).setA(5).setB(\"str\").build();\r\n *\r\n * @param type the name of the class to instantiate.\r\n * @param template optional class partial which the builder will derive initial params from.\r\n * @param override optional class partial which the builder will override params from when calling build().\r\n */\r\nexport function Builder<T>(type: Clazz<T>, template?: Partial<T> | null, override?: Partial<T> | null): IBuilder<T>;\r\n\r\n/**\r\n * Create a Builder for an interface. Returned objects will be untyped.\r\n *\r\n * e.g. let obj: Interface = Builder<Interface>().setA(5).setB(\"str\").build();\r\n *\r\n * @param template optional partial object which the builder will derive initial params from.\r\n * @param override optional partial object which the builder will override params from when calling build().\r\n */\r\nexport function Builder<T>(template?: Partial<T> | null, override?: Partial<T> | null): IBuilder<T>;\r\n\r\nexport function Builder<T>(typeOrTemplate?: Clazz<T> | Partial<T> | null,\r\n                           templateOrOverride?: Partial<T> | null,\r\n                           override?: Partial<T> | null): IBuilder<T> {\r\n  let type: Clazz<T> | undefined;\r\n  let template: Partial<T> | null | undefined;\r\n  let overrideValues: Partial<T> | null | undefined;\r\n\r\n  if (typeOrTemplate instanceof Function) {\r\n    type = typeOrTemplate;\r\n    template = templateOrOverride;\r\n    overrideValues = override;\r\n  } else {\r\n    template = typeOrTemplate;\r\n    overrideValues = templateOrOverride;\r\n  }\r\n\r\n  const built: Record<string, unknown> = template ? Object.assign({}, template) : {};\r\n\r\n  const builder = new Proxy(\r\n    {},\r\n    {\r\n      get(target, prop) {\r\n        if ('build' === prop) {\r\n          if (overrideValues) {\r\n            Object.assign(built, overrideValues);\r\n          }\r\n\r\n          if (type) {\r\n            // A class name (identified by the constructor) was passed. Instantiate it with props.\r\n            const obj: T = new type();\r\n            return () => Object.assign(obj as T & Record<string, unknown>, {...built});\r\n          } else {\r\n            // No type information - just return the object.\r\n            return () => built;\r\n          }\r\n        }\r\n\r\n        return (...args: unknown[]): unknown => {\r\n          // If no arguments passed return current value.\r\n          if (0 === args.length) {\r\n            return built[prop.toString()];\r\n          }\r\n          \r\n          built[prop.toString()] = args[0];\r\n          return builder;\r\n        };\r\n      }\r\n    }\r\n  );\r\n\r\n  return builder as IBuilder<T>;\r\n}\r\n","export type IStrictBuilder<T, B = Record<string, unknown>> = {\r\n  [k in keyof T]-?: ((arg: T[k]) => IStrictBuilder<T, B & Record<k, T[k]>>) & (() => T[k]);\r\n}\r\n& {\r\n  build: B extends T ? () => T : never\r\n};\r\n\r\n/**\r\n * Create a StrictBuilder for an interface. Returned objects will be untyped.\r\n *\r\n * e.g. let obj: Interface = StrictBuilder<Interface>().setA(5).setB(\"str\").build();\r\n *\r\n */\r\nexport function StrictBuilder<T>(): IStrictBuilder<T> {\r\n\r\n  const built: Record<string, unknown> = {};\r\n\r\n  const strictbuilder = new Proxy(\r\n    {},\r\n    {\r\n      get(target, prop) {\r\n        if ('build' === prop) {\r\n          return () => built;\r\n        }\r\n\r\n        return (...args: unknown[]): unknown => {\r\n          // If no arguments passed return current value.\r\n          if (0 === args.length) {\r\n            return built[prop.toString()];\r\n          }\r\n          \r\n          built[prop.toString()] = args[0];\r\n          return strictbuilder as IStrictBuilder<T>;\r\n        };\r\n      }\r\n    }\r\n  );\r\n\r\n  return strictbuilder as IStrictBuilder<T>;\r\n}\r\n"],"mappings":";AA8BO,SAAS,QAAW,gBACA,oBACA,UAA2C;AACpE,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,0BAA0B,UAAU;AACtC,WAAO;AACP,eAAW;AACX,qBAAiB;AAAA,EACnB,OAAO;AACL,eAAW;AACX,qBAAiB;AAAA,EACnB;AAEA,QAAM,QAAiC,WAAW,OAAO,OAAO,CAAC,GAAG,QAAQ,IAAI,CAAC;AAEjF,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC;AAAA,IACD;AAAA,MACE,IAAI,QAAQ,MAAM;AAChB,YAAI,YAAY,MAAM;AACpB,cAAI,gBAAgB;AAClB,mBAAO,OAAO,OAAO,cAAc;AAAA,UACrC;AAEA,cAAI,MAAM;AAER,kBAAM,MAAS,IAAI,KAAK;AACxB,mBAAO,MAAM,OAAO,OAAO,KAAoC,EAAC,GAAG,MAAK,CAAC;AAAA,UAC3E,OAAO;AAEL,mBAAO,MAAM;AAAA,UACf;AAAA,QACF;AAEA,eAAO,IAAI,SAA6B;AAEtC,cAAI,MAAM,KAAK,QAAQ;AACrB,mBAAO,MAAM,KAAK,SAAS;AAAA,UAC7B;AAEA,gBAAM,KAAK,SAAS,KAAK,KAAK;AAC9B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACpEO,SAAS,gBAAsC;AAEpD,QAAM,QAAiC,CAAC;AAExC,QAAM,gBAAgB,IAAI;AAAA,IACxB,CAAC;AAAA,IACD;AAAA,MACE,IAAI,QAAQ,MAAM;AAChB,YAAI,YAAY,MAAM;AACpB,iBAAO,MAAM;AAAA,QACf;AAEA,eAAO,IAAI,SAA6B;AAEtC,cAAI,MAAM,KAAK,QAAQ;AACrB,mBAAO,MAAM,KAAK,SAAS;AAAA,UAC7B;AAEA,gBAAM,KAAK,SAAS,KAAK,KAAK;AAC9B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}