๐Ÿš€ Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more โ†’
Sign In

@cerios/cerios-builder

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cerios/cerios-builder - npm Package Compare versions

Comparing version
1.0.0
to
1.1.0
+69
-5
dist/index.d.mts
/**
* Unique symbol to track which properties have been set in the builder's type
* Unique symbol used internally to brand types and track which properties have been set in the builder's type.
*
* @internal
*/
declare const __brand: unique symbol;
/**
* Brand type to track set properties at the type level
* Type utility for branding builder types with information about which properties have been set.
* This is used to enforce compile-time safety for required fields in the builder pattern.
*
* @template T - The type representing the set of properties that have been set
* @internal
*/

@@ -12,5 +18,21 @@ type CeriosBrand<T> = {

/**
* Base Builder class that provides type-safe building with automatic property setters
* and compile-time validation of required fields.
* Abstract base class for creating type-safe builders with automatic property setters and compile-time validation of required fields.
*
* This class is intended to be extended by concrete builder implementations for your own types.
* It provides utility methods for setting properties and building the final object, ensuring that all required fields are set at compile time.
*
* Example usage:
* ```typescript
* interface MyType { foo: string; bar: number[]; }
* class MyTypeBuilder extends CeriosBuilder<MyType> {
* setFoo(value: string) { return this.setProperty('foo', value); }
* addBar(value: number) { return this.addToArrayProperty('bar', value); }
* }
* // Usage:
* const obj = new MyTypeBuilder({})
* .setFoo('hello')
* .addBar(42)
* .build();
* ```
*
* @template T - The complete type being built

@@ -20,9 +42,42 @@ */

protected readonly _actual: Partial<T>;
/**
* Creates a new builder instance. Intended to be called by subclasses.
*
* @param _actual - The current partial state of the object being built
* @protected
*/
protected constructor(_actual: Partial<T>);
/**
* Sets a property value and returns a new builder instance with updated type state.
* This method tracks which properties have been set via the type system.
* This method is intended to be wrapped by concrete builder methods in subclasses.
*
* @template K - The property key being set
* @param key - The property key to set
* @param value - The value to assign to the property
* @returns A new builder instance with the property set and type state updated
* @protected
*/
protected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>>;
/**
* Sets multiple property values at once and returns a new builder instance with updated type state.
* @param props - An object with one or more properties to set.
* @returns A new builder instance with the properties set and type state updated.
* @protected
*/
protected setProperties<K extends keyof T>(props: Pick<T, K>): this & CeriosBrand<Pick<T, K>>;
/**
* Adds a value to an array property and returns a new builder instance with updated type state.
* This method is intended to be wrapped by concrete builder methods in subclasses for array properties.
*
* @template K - The property key (must be an array property)
* @template V - The type of the array element
* @param key - The array property key to add to
* @param value - The value to add to the array
* @returns A new builder instance with the array property updated and type state updated
* @protected
*/
protected addToArrayProperty<K extends {
[P in keyof T]: NonNullable<T[P]> extends Array<any> ? P : never;
}[keyof T], V extends T[K] extends Array<infer U> ? U : T[K] extends Array<infer U> | undefined ? U : never>(key: K, value: V): this & CeriosBrand<Pick<T, K>>;
/**
* Builds the final object. This method uses TypeScript's contextual typing to ensure

@@ -32,4 +87,13 @@ * all required fields are set before allowing build() to be called.

* The type constraint checks that all required properties are present.
*
* @returns The fully built object of type T
* @throws {TypeError} If called without all required fields set (compile-time error)
*/
build(this: this & CeriosBrand<T>): T;
/**
* Builds a partial object, which may not have all required fields set.
* This is useful for scenarios where you want to inspect or validate the current state before finalizing.
*
* @returns The partially built object
*/
buildPartial(): Partial<T>;

@@ -36,0 +100,0 @@ }

/**
* Unique symbol to track which properties have been set in the builder's type
* Unique symbol used internally to brand types and track which properties have been set in the builder's type.
*
* @internal
*/
declare const __brand: unique symbol;
/**
* Brand type to track set properties at the type level
* Type utility for branding builder types with information about which properties have been set.
* This is used to enforce compile-time safety for required fields in the builder pattern.
*
* @template T - The type representing the set of properties that have been set
* @internal
*/

@@ -12,5 +18,21 @@ type CeriosBrand<T> = {

/**
* Base Builder class that provides type-safe building with automatic property setters
* and compile-time validation of required fields.
* Abstract base class for creating type-safe builders with automatic property setters and compile-time validation of required fields.
*
* This class is intended to be extended by concrete builder implementations for your own types.
* It provides utility methods for setting properties and building the final object, ensuring that all required fields are set at compile time.
*
* Example usage:
* ```typescript
* interface MyType { foo: string; bar: number[]; }
* class MyTypeBuilder extends CeriosBuilder<MyType> {
* setFoo(value: string) { return this.setProperty('foo', value); }
* addBar(value: number) { return this.addToArrayProperty('bar', value); }
* }
* // Usage:
* const obj = new MyTypeBuilder({})
* .setFoo('hello')
* .addBar(42)
* .build();
* ```
*
* @template T - The complete type being built

@@ -20,9 +42,42 @@ */

protected readonly _actual: Partial<T>;
/**
* Creates a new builder instance. Intended to be called by subclasses.
*
* @param _actual - The current partial state of the object being built
* @protected
*/
protected constructor(_actual: Partial<T>);
/**
* Sets a property value and returns a new builder instance with updated type state.
* This method tracks which properties have been set via the type system.
* This method is intended to be wrapped by concrete builder methods in subclasses.
*
* @template K - The property key being set
* @param key - The property key to set
* @param value - The value to assign to the property
* @returns A new builder instance with the property set and type state updated
* @protected
*/
protected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>>;
/**
* Sets multiple property values at once and returns a new builder instance with updated type state.
* @param props - An object with one or more properties to set.
* @returns A new builder instance with the properties set and type state updated.
* @protected
*/
protected setProperties<K extends keyof T>(props: Pick<T, K>): this & CeriosBrand<Pick<T, K>>;
/**
* Adds a value to an array property and returns a new builder instance with updated type state.
* This method is intended to be wrapped by concrete builder methods in subclasses for array properties.
*
* @template K - The property key (must be an array property)
* @template V - The type of the array element
* @param key - The array property key to add to
* @param value - The value to add to the array
* @returns A new builder instance with the array property updated and type state updated
* @protected
*/
protected addToArrayProperty<K extends {
[P in keyof T]: NonNullable<T[P]> extends Array<any> ? P : never;
}[keyof T], V extends T[K] extends Array<infer U> ? U : T[K] extends Array<infer U> | undefined ? U : never>(key: K, value: V): this & CeriosBrand<Pick<T, K>>;
/**
* Builds the final object. This method uses TypeScript's contextual typing to ensure

@@ -32,4 +87,13 @@ * all required fields are set before allowing build() to be called.

* The type constraint checks that all required properties are present.
*
* @returns The fully built object of type T
* @throws {TypeError} If called without all required fields set (compile-time error)
*/
build(this: this & CeriosBrand<T>): T;
/**
* Builds a partial object, which may not have all required fields set.
* This is useful for scenarios where you want to inspect or validate the current state before finalizing.
*
* @returns The partially built object
*/
buildPartial(): Partial<T>;

@@ -36,0 +100,0 @@ }

@@ -29,2 +29,8 @@ "use strict";

var CeriosBuilder = class {
/**
* Creates a new builder instance. Intended to be called by subclasses.
*
* @param _actual - The current partial state of the object being built
* @protected
*/
constructor(_actual) {

@@ -35,3 +41,9 @@ this._actual = _actual;

* Sets a property value and returns a new builder instance with updated type state.
* This method tracks which properties have been set via the type system.
* This method is intended to be wrapped by concrete builder methods in subclasses.
*
* @template K - The property key being set
* @param key - The property key to set
* @param value - The value to assign to the property
* @returns A new builder instance with the property set and type state updated
* @protected
*/

@@ -46,2 +58,35 @@ setProperty(key, value) {

/**
* Sets multiple property values at once and returns a new builder instance with updated type state.
* @param props - An object with one or more properties to set.
* @returns A new builder instance with the properties set and type state updated.
* @protected
*/
setProperties(props) {
const BuilderClass = this.constructor;
return new BuilderClass({
...this._actual,
...props
});
}
/**
* Adds a value to an array property and returns a new builder instance with updated type state.
* This method is intended to be wrapped by concrete builder methods in subclasses for array properties.
*
* @template K - The property key (must be an array property)
* @template V - The type of the array element
* @param key - The array property key to add to
* @param value - The value to add to the array
* @returns A new builder instance with the array property updated and type state updated
* @protected
*/
addToArrayProperty(key, value) {
var _a;
const BuilderClass = this.constructor;
const currentArray = (_a = this._actual[key]) != null ? _a : [];
return new BuilderClass({
...this._actual,
[key]: [...currentArray, value]
});
}
/**
* Builds the final object. This method uses TypeScript's contextual typing to ensure

@@ -51,2 +96,5 @@ * all required fields are set before allowing build() to be called.

* The type constraint checks that all required properties are present.
*
* @returns The fully built object of type T
* @throws {TypeError} If called without all required fields set (compile-time error)
*/

@@ -56,2 +104,8 @@ build() {

}
/**
* Builds a partial object, which may not have all required fields set.
* This is useful for scenarios where you want to inspect or validate the current state before finalizing.
*
* @returns The partially built object
*/
buildPartial() {

@@ -58,0 +112,0 @@ return this._actual;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/cerios-builder.ts"],"sourcesContent":["export { CeriosBrand, CeriosBuilder } from \"./cerios-builder.js\";\n","/**\n * Unique symbol to track which properties have been set in the builder's type\n */\ndeclare const __brand: unique symbol;\n\n/**\n * Brand type to track set properties at the type level\n */\nexport type CeriosBrand<T> = { [__brand]: T };\n\n/**\n * Base Builder class that provides type-safe building with automatic property setters\n * and compile-time validation of required fields.\n *\n * @template T - The complete type being built\n */\nexport abstract class CeriosBuilder<T extends object> {\n\tprotected constructor(protected readonly _actual: Partial<T>) {}\n\n\t/**\n\t * Sets a property value and returns a new builder instance with updated type state.\n\t * This method tracks which properties have been set via the type system.\n\t */\n\tprotected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: value,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Builds the final object. This method uses TypeScript's contextual typing to ensure\n\t * all required fields are set before allowing build() to be called.\n\t *\n\t * The type constraint checks that all required properties are present.\n\t */\n\tbuild(this: this & CeriosBrand<T>): T {\n\t\treturn this._actual as T;\n\t}\n\n\tbuildPartial(): Partial<T> {\n\t\treturn this._actual as Partial<T>;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgBO,IAAe,gBAAf,MAA+C;AAAA,EAC3C,YAA+B,SAAqB;AAArB;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrD,YAA+B,KAAQ,OAA6C;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAsC;AACrC,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,eAA2B;AAC1B,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
{"version":3,"sources":["../src/index.ts","../src/cerios-builder.ts"],"sourcesContent":["export { CeriosBrand, CeriosBuilder } from \"./cerios-builder.js\";\n","/**\n * Unique symbol used internally to brand types and track which properties have been set in the builder's type.\n *\n * @internal\n */\ndeclare const __brand: unique symbol;\n\n/**\n * Type utility for branding builder types with information about which properties have been set.\n * This is used to enforce compile-time safety for required fields in the builder pattern.\n *\n * @template T - The type representing the set of properties that have been set\n * @internal\n */\nexport type CeriosBrand<T> = { [__brand]: T };\n\n/**\n * Abstract base class for creating type-safe builders with automatic property setters and compile-time validation of required fields.\n *\n * This class is intended to be extended by concrete builder implementations for your own types.\n * It provides utility methods for setting properties and building the final object, ensuring that all required fields are set at compile time.\n *\n * Example usage:\n * ```typescript\n * interface MyType { foo: string; bar: number[]; }\n * class MyTypeBuilder extends CeriosBuilder<MyType> {\n * setFoo(value: string) { return this.setProperty('foo', value); }\n * addBar(value: number) { return this.addToArrayProperty('bar', value); }\n * }\n * // Usage:\n * const obj = new MyTypeBuilder({})\n * .setFoo('hello')\n * .addBar(42)\n * .build();\n * ```\n *\n * @template T - The complete type being built\n */\nexport abstract class CeriosBuilder<T extends object> {\n\t/**\n\t * Creates a new builder instance. Intended to be called by subclasses.\n\t *\n\t * @param _actual - The current partial state of the object being built\n\t * @protected\n\t */\n\tprotected constructor(protected readonly _actual: Partial<T>) {}\n\n\t/**\n\t * Sets a property value and returns a new builder instance with updated type state.\n\t * This method is intended to be wrapped by concrete builder methods in subclasses.\n\t *\n\t * @template K - The property key being set\n\t * @param key - The property key to set\n\t * @param value - The value to assign to the property\n\t * @returns A new builder instance with the property set and type state updated\n\t * @protected\n\t */\n\tprotected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: value,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Sets multiple property values at once and returns a new builder instance with updated type state.\n\t * @param props - An object with one or more properties to set.\n\t * @returns A new builder instance with the properties set and type state updated.\n\t * @protected\n\t */\n\tprotected setProperties<K extends keyof T>(props: Pick<T, K>): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t...props,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Adds a value to an array property and returns a new builder instance with updated type state.\n\t * This method is intended to be wrapped by concrete builder methods in subclasses for array properties.\n\t *\n\t * @template K - The property key (must be an array property)\n\t * @template V - The type of the array element\n\t * @param key - The array property key to add to\n\t * @param value - The value to add to the array\n\t * @returns A new builder instance with the array property updated and type state updated\n\t * @protected\n\t */\n\tprotected addToArrayProperty<\n\t\tK extends { [P in keyof T]: NonNullable<T[P]> extends Array<any> ? P : never }[keyof T],\n\t\tV extends T[K] extends Array<infer U> ? U : T[K] extends Array<infer U> | undefined ? U : never,\n\t>(key: K, value: V): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\tconst currentArray = (this._actual[key] as Array<V> | undefined) ?? [];\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: [...currentArray, value],\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Builds the final object. This method uses TypeScript's contextual typing to ensure\n\t * all required fields are set before allowing build() to be called.\n\t *\n\t * The type constraint checks that all required properties are present.\n\t *\n\t * @returns The fully built object of type T\n\t * @throws {TypeError} If called without all required fields set (compile-time error)\n\t */\n\tbuild(this: this & CeriosBrand<T>): T {\n\t\treturn this._actual as T;\n\t}\n\n\t/**\n\t * Builds a partial object, which may not have all required fields set.\n\t * This is useful for scenarios where you want to inspect or validate the current state before finalizing.\n\t *\n\t * @returns The partially built object\n\t */\n\tbuildPartial(): Partial<T> {\n\t\treturn this._actual as Partial<T>;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsCO,IAAe,gBAAf,MAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3C,YAA+B,SAAqB;AAArB;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYrD,YAA+B,KAAQ,OAA6C;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,cAAiC,OAAmD;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACJ,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,mBAGR,KAAQ,OAA0C;AA7FrD;AA8FE,UAAM,eAAe,KAAK;AAC1B,UAAM,gBAAgB,UAAK,QAAQ,GAAG,MAAhB,YAA8C,CAAC;AACrE,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG,CAAC,GAAG,cAAc,KAAK;AAAA,IAC/B,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAsC;AACrC,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAA2B;AAC1B,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
// src/cerios-builder.ts
var CeriosBuilder = class {
/**
* Creates a new builder instance. Intended to be called by subclasses.
*
* @param _actual - The current partial state of the object being built
* @protected
*/
constructor(_actual) {

@@ -8,3 +14,9 @@ this._actual = _actual;

* Sets a property value and returns a new builder instance with updated type state.
* This method tracks which properties have been set via the type system.
* This method is intended to be wrapped by concrete builder methods in subclasses.
*
* @template K - The property key being set
* @param key - The property key to set
* @param value - The value to assign to the property
* @returns A new builder instance with the property set and type state updated
* @protected
*/

@@ -19,2 +31,35 @@ setProperty(key, value) {

/**
* Sets multiple property values at once and returns a new builder instance with updated type state.
* @param props - An object with one or more properties to set.
* @returns A new builder instance with the properties set and type state updated.
* @protected
*/
setProperties(props) {
const BuilderClass = this.constructor;
return new BuilderClass({
...this._actual,
...props
});
}
/**
* Adds a value to an array property and returns a new builder instance with updated type state.
* This method is intended to be wrapped by concrete builder methods in subclasses for array properties.
*
* @template K - The property key (must be an array property)
* @template V - The type of the array element
* @param key - The array property key to add to
* @param value - The value to add to the array
* @returns A new builder instance with the array property updated and type state updated
* @protected
*/
addToArrayProperty(key, value) {
var _a;
const BuilderClass = this.constructor;
const currentArray = (_a = this._actual[key]) != null ? _a : [];
return new BuilderClass({
...this._actual,
[key]: [...currentArray, value]
});
}
/**
* Builds the final object. This method uses TypeScript's contextual typing to ensure

@@ -24,2 +69,5 @@ * all required fields are set before allowing build() to be called.

* The type constraint checks that all required properties are present.
*
* @returns The fully built object of type T
* @throws {TypeError} If called without all required fields set (compile-time error)
*/

@@ -29,2 +77,8 @@ build() {

}
/**
* Builds a partial object, which may not have all required fields set.
* This is useful for scenarios where you want to inspect or validate the current state before finalizing.
*
* @returns The partially built object
*/
buildPartial() {

@@ -31,0 +85,0 @@ return this._actual;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/cerios-builder.ts"],"sourcesContent":["/**\n * Unique symbol to track which properties have been set in the builder's type\n */\ndeclare const __brand: unique symbol;\n\n/**\n * Brand type to track set properties at the type level\n */\nexport type CeriosBrand<T> = { [__brand]: T };\n\n/**\n * Base Builder class that provides type-safe building with automatic property setters\n * and compile-time validation of required fields.\n *\n * @template T - The complete type being built\n */\nexport abstract class CeriosBuilder<T extends object> {\n\tprotected constructor(protected readonly _actual: Partial<T>) {}\n\n\t/**\n\t * Sets a property value and returns a new builder instance with updated type state.\n\t * This method tracks which properties have been set via the type system.\n\t */\n\tprotected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: value,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Builds the final object. This method uses TypeScript's contextual typing to ensure\n\t * all required fields are set before allowing build() to be called.\n\t *\n\t * The type constraint checks that all required properties are present.\n\t */\n\tbuild(this: this & CeriosBrand<T>): T {\n\t\treturn this._actual as T;\n\t}\n\n\tbuildPartial(): Partial<T> {\n\t\treturn this._actual as Partial<T>;\n\t}\n}\n"],"mappings":";AAgBO,IAAe,gBAAf,MAA+C;AAAA,EAC3C,YAA+B,SAAqB;AAArB;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrD,YAA+B,KAAQ,OAA6C;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAsC;AACrC,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,eAA2B;AAC1B,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
{"version":3,"sources":["../src/cerios-builder.ts"],"sourcesContent":["/**\n * Unique symbol used internally to brand types and track which properties have been set in the builder's type.\n *\n * @internal\n */\ndeclare const __brand: unique symbol;\n\n/**\n * Type utility for branding builder types with information about which properties have been set.\n * This is used to enforce compile-time safety for required fields in the builder pattern.\n *\n * @template T - The type representing the set of properties that have been set\n * @internal\n */\nexport type CeriosBrand<T> = { [__brand]: T };\n\n/**\n * Abstract base class for creating type-safe builders with automatic property setters and compile-time validation of required fields.\n *\n * This class is intended to be extended by concrete builder implementations for your own types.\n * It provides utility methods for setting properties and building the final object, ensuring that all required fields are set at compile time.\n *\n * Example usage:\n * ```typescript\n * interface MyType { foo: string; bar: number[]; }\n * class MyTypeBuilder extends CeriosBuilder<MyType> {\n * setFoo(value: string) { return this.setProperty('foo', value); }\n * addBar(value: number) { return this.addToArrayProperty('bar', value); }\n * }\n * // Usage:\n * const obj = new MyTypeBuilder({})\n * .setFoo('hello')\n * .addBar(42)\n * .build();\n * ```\n *\n * @template T - The complete type being built\n */\nexport abstract class CeriosBuilder<T extends object> {\n\t/**\n\t * Creates a new builder instance. Intended to be called by subclasses.\n\t *\n\t * @param _actual - The current partial state of the object being built\n\t * @protected\n\t */\n\tprotected constructor(protected readonly _actual: Partial<T>) {}\n\n\t/**\n\t * Sets a property value and returns a new builder instance with updated type state.\n\t * This method is intended to be wrapped by concrete builder methods in subclasses.\n\t *\n\t * @template K - The property key being set\n\t * @param key - The property key to set\n\t * @param value - The value to assign to the property\n\t * @returns A new builder instance with the property set and type state updated\n\t * @protected\n\t */\n\tprotected setProperty<K extends keyof T>(key: K, value: T[K]): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: value,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Sets multiple property values at once and returns a new builder instance with updated type state.\n\t * @param props - An object with one or more properties to set.\n\t * @returns A new builder instance with the properties set and type state updated.\n\t * @protected\n\t */\n\tprotected setProperties<K extends keyof T>(props: Pick<T, K>): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t...props,\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Adds a value to an array property and returns a new builder instance with updated type state.\n\t * This method is intended to be wrapped by concrete builder methods in subclasses for array properties.\n\t *\n\t * @template K - The property key (must be an array property)\n\t * @template V - The type of the array element\n\t * @param key - The array property key to add to\n\t * @param value - The value to add to the array\n\t * @returns A new builder instance with the array property updated and type state updated\n\t * @protected\n\t */\n\tprotected addToArrayProperty<\n\t\tK extends { [P in keyof T]: NonNullable<T[P]> extends Array<any> ? P : never }[keyof T],\n\t\tV extends T[K] extends Array<infer U> ? U : T[K] extends Array<infer U> | undefined ? U : never,\n\t>(key: K, value: V): this & CeriosBrand<Pick<T, K>> {\n\t\tconst BuilderClass = this.constructor as new (data: any) => any;\n\t\tconst currentArray = (this._actual[key] as Array<V> | undefined) ?? [];\n\t\treturn new BuilderClass({\n\t\t\t...this._actual,\n\t\t\t[key]: [...currentArray, value],\n\t\t}) as this & CeriosBrand<Pick<T, K>>;\n\t}\n\n\t/**\n\t * Builds the final object. This method uses TypeScript's contextual typing to ensure\n\t * all required fields are set before allowing build() to be called.\n\t *\n\t * The type constraint checks that all required properties are present.\n\t *\n\t * @returns The fully built object of type T\n\t * @throws {TypeError} If called without all required fields set (compile-time error)\n\t */\n\tbuild(this: this & CeriosBrand<T>): T {\n\t\treturn this._actual as T;\n\t}\n\n\t/**\n\t * Builds a partial object, which may not have all required fields set.\n\t * This is useful for scenarios where you want to inspect or validate the current state before finalizing.\n\t *\n\t * @returns The partially built object\n\t */\n\tbuildPartial(): Partial<T> {\n\t\treturn this._actual as Partial<T>;\n\t}\n}\n"],"mappings":";AAsCO,IAAe,gBAAf,MAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3C,YAA+B,SAAqB;AAArB;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYrD,YAA+B,KAAQ,OAA6C;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,cAAiC,OAAmD;AAC7F,UAAM,eAAe,KAAK;AAC1B,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACJ,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,mBAGR,KAAQ,OAA0C;AA7FrD;AA8FE,UAAM,eAAe,KAAK;AAC1B,UAAM,gBAAgB,UAAK,QAAQ,GAAG,MAAhB,YAA8C,CAAC;AACrE,WAAO,IAAI,aAAa;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,CAAC,GAAG,GAAG,CAAC,GAAG,cAAc,KAAK;AAAA,IAC/B,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAsC;AACrC,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAA2B;AAC1B,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
{
"name": "@cerios/cerios-builder",
"version": "1.0.0",
"version": "1.1.0",
"author": "Ronald Veth - Cerios",
"description": "A TypeScript project with Jest testing framework",
"description": "A TypeScript builder pattern library providing compile-time type safety for object construction with method chaining and required field validation",
"license": "MIT",

@@ -7,0 +7,0 @@ "keywords": ["typescript", "builder-pattern", "object-construction", "cerios"],

+65
-20

@@ -13,2 +13,3 @@ # @cerios/cerios-builder

- **TypeScript First**: Built with TypeScript, for TypeScript
- **Array Property Helpers**: Easily add values to array properties with type safety

@@ -39,2 +40,3 @@ ## ๐Ÿ“ฆ Installation

age?: number; // Optional property
roles?: string[]; // Optional array property
};

@@ -44,6 +46,2 @@

class UserBuilder extends CeriosBuilder<User> {
private constructor(data: Partial<User>) {
super(data);
}
static create() {

@@ -69,2 +67,7 @@ return new UserBuilder({});

// New: Add to array property
addRole(role: string) {
return this.addToArrayProperty('roles', role);
}
// Custom methods for common patterns

@@ -90,5 +93,7 @@ withRandomId() {

.age(30)
.addRole("admin") // Add to array property
.addRole("editor")
.build();
// โœ… Optional fields can be omitted
// โœ… Optional fields and arrays can be omitted
const basicUser = UserBuilder.create()

@@ -98,3 +103,3 @@ .id("456")

.email("jane@example.com")
.build(); // age is optional, so this works
.build(); // age and roles are optional

@@ -115,2 +120,3 @@ // โŒ This won't compile - missing required 'email' field

.withAdminEmail("admin")
.addRole("admin")
.age(25)

@@ -120,3 +126,3 @@ .build();

console.log(adminUser);
// Output: { id: "550e8400-...", name: "Admin User", email: "admin@admin.company.com", age: 25 }
// Output: { id: "550e8400-...", name: "Admin User", email: "admin@admin.company.com", roles: ["admin"], age: 25 }
```

@@ -132,6 +138,2 @@

class ProductBuilder extends CeriosBuilder<Product> {
private constructor(data: Partial<Product>) {
super(data);
}
static create() {

@@ -153,2 +155,7 @@ return new ProductBuilder({});

// Add to array property
addTag(tag: string) {
return this.addToArrayProperty('tags', tag);
}
// Custom methods for testing

@@ -173,2 +180,4 @@ asElectronics() {

.asElectronics()
.addTag("featured")
.addTag("sale")
.build();

@@ -192,9 +201,6 @@ ```

phoneNumber?: string;
notes?: string[];
};
class AddressBuilder extends CeriosBuilder<Address> {
private constructor(data: Partial<Address>) {
super(data);
}
static create() {

@@ -204,2 +210,9 @@ return new AddressBuilder({});

static createWithDefaults() {
return this.create().setProperties({
city: "Othertown",
country: "United States",
});
}
street(value: string) {

@@ -228,6 +241,2 @@ return this.setProperty('street', value);

class CustomerBuilder extends CeriosBuilder<Customer> {
private constructor(data: Partial<Customer>) {
super(data);
}
static create() {

@@ -253,2 +262,7 @@ return new CustomerBuilder({});

// Add to array property
addNote(note: string) {
return this.addToArrayProperty('notes', note);
}
// Build address inline

@@ -259,5 +273,15 @@ withAddress(builderFn: (builder: AddressBuilder) => AddressBuilder & CeriosBrand<Address>) {

}
// Build address with defaults (pre-sets city and country)
withAddressDefaults(
builderFn: (
builder: AddressBuilder & CeriosBrand<Pick<Address, "city" | "country">>
) => AddressBuilder & CeriosBrand<Address>
) {
const address = builderFn(AddressBuilder.createWithDefaults()).build();
return this.setProperty('address', address);
}
}
// Usage
// Usage with full address
const customer = CustomerBuilder.create()

@@ -272,4 +296,17 @@ .id('CUST-001')

)
.addNote("VIP customer")
.addNote("Prefers email contact")
.phoneNumber('+1-555-0123')
.build();
// Usage with defaults (only set street, city/country are pre-filled)
const customerWithDefaults = CustomerBuilder.create()
.id('CUST-002')
.name('Bob Smith')
.withAddressDefaults(addr => addr.street('456 Elm St')) // city and country are already set to defaults
.addNote("New customer")
.build();
console.log(customerWithDefaults);
// Output: { id: 'CUST-002', name: 'Bob Smith', address: { street: '456 Elm St', city: 'Othertown', country: 'United States' }, notes: ['New customer'] }
```

@@ -285,2 +322,3 @@

.name("Unknown User")
.addRole("guest")
.buildPartial(); // Returns Partial<User>

@@ -305,2 +343,3 @@

.email('test@example.com')
.addRole('tester')
.age(25)

@@ -313,2 +352,3 @@ .build();

expect(result.user.name).toBe('Test User');
expect(result.user.roles).toContain('tester');
});

@@ -321,2 +361,3 @@

.email('ageless@example.com')
.addRole('guest')
.build();

@@ -328,2 +369,3 @@

expect(result.user.age).toBeUndefined();
expect(result.user.roles).toContain('guest');
});

@@ -342,2 +384,3 @@ });

// Oops! Forgot required email field
roles: ["admin"]
};

@@ -356,2 +399,3 @@

.email("john@example.com") // Required - won't compile without it
.addRole("admin")
.build();

@@ -372,2 +416,3 @@

- `setProperty<K>(key: K, value: T[K])` - Sets a property and returns a new builder instance
- `addToArrayProperty<K, V>(key: K, value: V)` - Adds a value to an array property and returns a new builder instance
- `build()` - Builds the final object (only available when all required properties are set)

@@ -374,0 +419,0 @@ - `buildPartial()` - Builds a partial object with currently set properties