<commit_before>import { fixStack } from './utils'

interface CustomError extends Error {}

interface CustomProperties {
	[property: string]: any
}

interface CustomConstructor<Properties> extends ErrorConstructor {
	readonly prototype: CustomError
	new (...args): CustomError & Properties
	(...args): CustomError & Properties
}

export function customErrorFactory<Properties = CustomError>(
	fn: (...Arguments) => void,
	parent: ErrorConstructor = Error,
): CustomConstructor<Properties> {
	function CustomError(this: CustomError, ...args: any[]): void {
		// allow simple function call
		if (!(this instanceof CustomError)) return new CustomError(...args)
		// apply super
		parent.apply(this, args)
		// apply custom fn
		fn.apply(this, args)
		// try to remove contructor from stack trace
		fixStack(this, CustomError)
	}

	return Object.defineProperties(CustomError, {
		prototype: {
			value: Object.create(parent.prototype, {
				constructor: {
					value: CustomError,
					writable: true,
					configurable: true,
				},
			}),
		},
	})
}<commit_msg>feat: Export factory Typescript Interfaces<commit_after>import { fixStack } from './utils'

export interface CustomErrorInterface extends Error {}

export interface CustomErrorConstructor<Properties> extends ErrorConstructor {
	readonly prototype: CustomErrorInterface
	new (...args): CustomErrorInterface & Properties
	(...args): CustomErrorInterface & Properties
}

export interface CustomErrorProperties {
	[property: string]: any
}

export function customErrorFactory<Properties = CustomErrorProperties>(
	fn: (...Arguments) => void,
	parent: ErrorConstructor = Error,
): CustomErrorConstructor<Properties> {
	function CustomError(this: CustomErrorInterface, ...args: any[]): void {
		// allow simple function call
		if (!(this instanceof CustomError)) return new CustomError(...args)
		// apply super
		parent.apply(this, args)
		// apply custom fn
		fn.apply(this, args)
		// try to remove contructor from stack trace
		fixStack(this, CustomError)
	}

	return Object.defineProperties(CustomError, {
		prototype: {
			value: Object.create(parent.prototype, {
				constructor: {
					value: CustomError,
					writable: true,
					configurable: true,
				},
			}),
		},
	})
}
{'fraction_non_alphanumeric': 0.11583184257602862, 'fraction_numerical': 0.0, 'mean_word_length': 4.300947867298579, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1403406', 'n_tokens_mistral': 675, 'n_tokens_neox': 604, 'n_words': 177}