UNPKG

@typescript-package/affix

Version:

A lightweight TypeScript library for different kind of affixes.

583 lines (573 loc) 23.3 kB
/** * @description A core abstract class to manage affixes with the value and kind that can be applied to strings. * @export * @abstract * @class AffixCore * @template {string | [string, string]} [Value=string | [string, string]] The type of affix constrained by the `string` and tuple of strings. Defaults to `string`. * @template {BasicAffixKind | undefined} [Kind=BasicAffixKind | undefined] The kind of affix. */ class AffixCore { /** * @description Checks if the given instance is an instance of `AffixCore`. * @public * @static * @param {any} instance The instance to check. * @returns {boolean} The boolean value indicating whether the instance is of type `AffixCore`. */ static is(instance) { return Object.prototype.toString.call(instance).match(/\[object (\w+)]/)?.[1] === this.tagName; } /** * @description Tag name for the `toStringTag`. * @public * @static * @type {string} */ static tagName = 'AffixCore'; /** * @description Returns the `string` tag representation of the `Affix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return AffixCore.tagName; } /** * @description Returns the kind of affix. * @public * @readonly * @type {(Kind)} */ get kind() { return this.#kind; } /** * @description Returns the privately stored affix of generic type variable `Value` constrained by `string` type. * @public * @readonly * @type {Value} */ get value() { return this.#value; } /** * @description Privately stored kind of `Kind` to define the type of affix. * @type {Kind | undefined} */ #kind; /** * @description Privately stored affix of generic type variable `Value` constrained by `string` type. * @type {Value} */ #value; /** * Creates an instance of `AffixCore`. * @constructor * @param {Value} value An optional initial affix of generic type variable `Value` constrained by `string` type. Defaults to `Affix.pattern`. * @param {?Kind} [kind] The kind of generic type variable `Kind` constrained by `BasicAffixKind` type. Defaults to `undefined`. */ constructor(value, kind) { this.#kind = kind; this.#value = value; } /** * @description Sets the kind of affix. * @public * @param {Kind} kind The kind of generic type variable `Kind` constrained by `BasicAffixKind` type. * @returns {this} The returned value is current instance for method chaining. */ setKind(kind) { this.#kind = kind; return this; } /** * @description Sets the value of the affix, sanitizing it according to the defined pattern. * @public * @param {Value} value * @returns {this} */ setValue(value) { this.#value = value; return this; } } // Abstract. /** * @description A concrete class to manage affixes that can be applied to strings with additional sanitization. * @export * @class Affix * @template {string | [string, string]} [Value=string | [string, string]] The type of affix constrained by the `string`. Defaults to `string`. * @template {BasicAffixKind | undefined} [Kind=BasicAffixKind | undefined] * @template {RegExp | string | undefined} [Pattern=RegExp | string | undefined] */ class Affix extends AffixCore { /** * @description Defines the affix sanitized by specified pattern. * @public * @static * @template {string | [string, string]} [Value=string | [string, string]] The type of affix constrained by the `string` type. Defaults to `string`. * @param {Value} value A value of generic type variable `Value` constrained by the `string` type to be sanitized with the `pattern`. * @param {RegExp | string} [pattern=Affix.pattern] The pattern of `RegExp` to sanitize the `affix`. Defaults to static `Affix.pattern`. * @returns {Value} The returned value is an affix of a generic type variable `Value`, optionally sanitized by the `pattern`. */ static sanitize(value, pattern = this.pattern) { return (typeof value === 'string' ? value.replace(pattern, '') : value.map(v => v.replace(pattern, ''))); } /** * @description The default pattern used to sanitize the affix, which removes characters that are not part of the valid characters for the affix. * @public * @static * @type {RegExp | string} */ static pattern = /[^a-zA-Z0-9$_]/g; /** * @description Tag name for the `toStringTag`. * @public * @static * @type {string} */ static tagName = Affix.name; /** * @description Returns the `string` tag representation of the `Affix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return Affix.tagName; } /** * @description Returns the privately stored pattern of `PatternValue` type to sanitize the affix. * @public * @readonly * @type {(Pattern)} */ get pattern() { return this.#pattern; } /** * @description Privately stored pattern of `Pattern` to sanitize the affix. * @type {Pattern | undefined} */ #pattern; /** * Creates an instance of `Affix`. * @constructor * @param {Value} value An optional initial affix of generic type variable `Value` constrained by `string` type. Defaults to `Affix.pattern`. * @param {{ kind?: Kind, pattern?: Pattern }} [param0={}] The options object to set the kind and pattern of the affix. * @param {Kind} param0.kind The kind of affix constrained by `BasicAffixKind` type. * @param {Pattern} param0.pattern The pattern of `PatternValue` to sanitize the affix. */ constructor(value, { kind, pattern } = {}) { super(Affix.sanitize(value, pattern), kind); this.#pattern = pattern ?? Affix.pattern; } /** * @description Returns the affix, optionally sanitized by the `pattern`. * @public * @param {(Pattern)} [pattern=this.#pattern] The pattern of `RegExp` to sanitize privately stored affix. * @returns {Value} Returns privately stored `#affix` of `Value` type optionally sanitized by the `pattern`. */ get(pattern = this.#pattern) { return Affix.sanitize(super.value, pattern); } /** * @description Sets and stores privately sanitized affix of generic type variable `Value` constrained by `string` type. * @public * @param {({ kind?: Kind, pattern?: Pattern, value?: Value})} [param0={}] * @param {Kind} param0.kind The kind of affix constrained by `BasicAffixKind` type. * @param {Pattern} param0.pattern The pattern of `Pattern` to sanitize the affix. * @param {Value} param0.value The value of the affix constrained by `string` type. * @returns {this} The returned value is current instance for method chaining. */ set({ kind, pattern, value } = {}) { typeof value === 'string' && this.setValue(Affix.sanitize(value, pattern)); 'kind' in arguments[0] && this.setKind(kind); 'pattern' in arguments[0] && this.setPattern(pattern); return this; } /** * @description Sets the pattern to sanitize the affix. * @public * @param {Pattern} pattern The pattern of `Pattern` to sanitize the affix. * @returns {this} The returned value is current instance for method chaining. */ setPattern(pattern) { this.#pattern = pattern; return this; } } // Class. /** * @description A class to manage circumfixes that can be applied to strings. * @export * @class Circumfix * @template {string} [Start=string] The type of circumfix constrained by the `string`. Defaults to `string`. * @template {string} [End=Start] The type of circumfix end constrained by the `string`, defaults to the same type as `Start`. * @template {RegExp | string | undefined} [Pattern=RegExp | string | undefined] The type of pattern constrained by the `RegExp` or `string`. * @extends {Affix<[Start, End], 'circumfix', Pattern>} */ class Circumfix extends Affix { /** * @description Inserts a circumfix to a given stem with an optional delimiter. * @public * @static * @template {string} [Start=string] The type of circumfix start constrained by the `string`. Defaults to `string`. * @template {string} [Stem=string] The type of stem constrained by the `string`. Defaults to `string`. * @template {string} [End=Start] The type of circumfix end constrained by the `string`, defaults to the same type as `Start`. * @template {string} [Delimiter=''] The type of delimiter constrained by the `string`, defaults to an empty string. * @param {Stem} stem The stem to which the circumfix will be inserted. * @param {(Start | [Start, End])} [circumfix=Circumfix.default as Start] The circumfix to be applied. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to be used. * @returns {CircumfixTemplate<Start, Stem, End, Delimiter>} The resulting circumfixed string. */ static insert(stem, circumfix = Circumfix.default, delimiter = '') { return `${typeof circumfix === 'string' ? circumfix : circumfix[0]}${delimiter}${stem}${delimiter}${typeof circumfix === 'string' ? circumfix : circumfix[1]}`; } /** * @inheritdoc * @public * @static * @type {string} */ static tagName = 'Circumfix'; /** * @description The default circumfix value, which is an empty string. This is used when no circumfix is provided. * @public * @static * @type {string | [string, string]} */ static default = ''; /** * @description Returns the `string` tag representation of the `Circumfix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return Circumfix.tagName; } /** * @description The circumfix value, which is a tuple containing the start and end of the circumfix. * @public * @readonly * @type {[Start, End]} */ get circumfix() { return this.value; } /** * @description The end of the circumfix, which is the second element of the tuple. * @public * @readonly * @type {End} */ get end() { return this.value[1]; } /** * @description The start of the circumfix, which is the first element of the tuple. * @public * @readonly * @type {Start} */ get start() { return this.value[0]; } /** * Creates an instance of `Circumfix`. * @constructor * @param {Start} [start='' as Value] The value of the prefix, constrained by the `string` type. Defaults to an empty string. * @param {End} [end=start as End] The value of the suffix, constrained by the `string` type, defaults to the same type as `start`. * @param {Pattern} [pattern=Circumfix.pattern] The pattern to sanitize the prefix. Defaults to the static `Circumfix.pattern`. */ constructor(start = '', end = start, pattern = Circumfix.pattern) { super([start, end], { kind: 'circumfix', pattern }); } /** * @description Inserts the circumfix to a given stem with an optional delimiter. * @param {string} stem The stem to which the circumfix will be inserted. * @returns {string} The resulting string with the circumfix inserted. */ insertTo(stem, delimiter = '') { return Circumfix.insert(stem, [this.start, this.end], delimiter); } } // Class. /** * @description A class to manage infixes that can be applied to strings. * @export * @class Infix * @template {string} [Value=string] The type of infix constrained by the `string`. * @template {RegExp | string | undefined} [Pattern=RegExp | string | undefined] The type of pattern constrained by the `RegExp` or `string`. * @extends {Affix<Value, 'infix', Pattern>} */ class Infix extends Affix { /** * @description Inserts the infix into a given stem at a specified position with an optional delimiter. * @public * @static * @template {string} Infix Type of the infix constrained by the `string`. * @template {string} [Stem=string] The type of the stem string. * @template {number} [Position=number] The type of the position number, defaults to `Math.floor(stem.length / 2)`. * @template {string} [Delimiter=''] The type of delimiter string, defaults to an empty string. * @param {Infix} infix The infix to insert into the stem at specified position. * @param {Stem} stem The stem to insert the infix into its specified position. * @param {Position} [position=Math.floor(stem.length / 2) as Position] The position of stem to insert the infix. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to use between the two halves of stem and infix. * @returns {InfixTemplate<SplitAt<Stem, Position>[0], Infix, SplitAt<Stem, Position>[1], Delimiter>} */ static insert(stem, infix, position = Math.floor(stem.length / 2), delimiter = '') { return `${stem.slice(0, position)}${delimiter}${infix}${delimiter}${stem.slice(position)}`; } /** * @description Tag name for the `toStringTag`. * @public * @static * @type {string} */ static tagName = 'Infix'; /** * @description The default infix to use. * @public * @static * @type {string} */ static default = ''; /** * @description Returns the `string` tag representation of the `Infix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return Infix.tagName; } /** * @description The infix value, which is a generic type variable `Value` constrained by the `string` type. * @public * @readonly * @type {Value} */ get infix() { return this.value; } /** * Creates an instance of `Infix`. * @constructor * @param {Value} [value='' as Value] The value of the infix, constrained by the `string` type. Defaults to an empty string. * @param {Pattern} [pattern=Infix.pattern] The pattern to sanitize the infix. Defaults to the static `Infix.pattern`. */ constructor(value = '', pattern = Infix.pattern) { super(value, { kind: 'infix', pattern }); } /** * @description Inserts the infix into a given stem at a specified position with an optional delimiter. * @public * @template {string} [Stem=string] The type of the stem string. * @template {number} [Position=number] The type of the position number, defaults to `Math.floor(stem.length / 2)`. * @template {string} [Delimiter=''] The type of delimiter string, defaults to an empty string. * @param {Stem} stem The stem to insert the infix into specified position of stem. * @param {Position} [position=Math.floor(stem.length / 2) as Position] The position of stem to insert the infix. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to use between the two halves of stem and infix. * @returns {InfixTemplate<SplitAt<Stem, Position>[0], Value, SplitAt<Stem, Position>[1], Delimiter>} */ insertTo(stem, position = Math.floor(stem.length / 2), delimiter = '') { return Infix.insert(stem, this.value, position, delimiter); } } // Class. /** * @description A class to manage prefixes that can be applied to strings. * @export * @class Prefix * @template {string} [Value=string] The type of prefix constrained by the `string`. * @template {RegExp | string | undefined} [Pattern=RegExp | string | undefined] The type of pattern constrained by the `RegExp` or `string`. * @extends {Affix<Value, 'prefix', Pattern>} */ class Prefix extends Affix { /** * @description Prepends the prefix to stem string. * @public * @static * @template {string} [Stem=string] The type of stem string constrained by the `string`. * @template {string} [Prefix=string] The type of prefix constrained by the `string`. * @param {Stem} stem The stem string to append the prefix. * @param {Prefix} [prefix=Prefix.default as Prefix] Prefix to append to stem. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to use between the prefix and the stem. * @param {boolean} [sanitize=true] Whether to sanitize the prefix using the static `Prefix.pattern`. * @returns {PrefixTemplate<Prefix, Stem, Delimiter>} */ static prepend(stem, prefix = Prefix.default, delimiter = '', sanitize = true) { return `${sanitize ? super.sanitize(prefix, this.pattern) : prefix}${delimiter}${stem}`; } /** * @description Tag name for the `toStringTag`. * @public * @static * @type {string} */ static tagName = 'Prefix'; /** * @description The default prefix to use. * @public * @static * @type {string} */ static default = ''; /** * @description Returns the `string` tag representation of the `Prefix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return Prefix.tagName; } /** * @description The prefix value of the generic type variable `Value` constrained by the `string` type. * @public * @readonly * @type {Value} */ get prefix() { return this.value; } /** * Creates an instance of `Prefix`. * @constructor * @param {Value} [value='' as Value] The value of the prefix, constrained by the `string` type. Defaults to an empty string. * @param {Pattern} [pattern=Prefix.pattern] The pattern to sanitize the prefix. Defaults to the static `Prefix.pattern`. */ constructor(value = '', pattern = Prefix.pattern) { super(value, { kind: 'prefix', pattern }); } /** * @description Prepends the prefix to stem string. * @public * @template {string} [Stem=string] The type of the stem string. * @template {string} [Delimiter=''] The type of delimiter string. * @param {Stem} stem The stem to prepend the prefix. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to use between the prefix and the stem. * @returns {PrefixTemplate<Value, Stem, Delimiter>} The resulting string with the prefix prepended. */ prependTo(stem, delimiter = '') { return Prefix.prepend(stem, Prefix.sanitize(this.prefix, this.pattern), delimiter); } /** * Sets the pattern and value for the prefix affix. * @inheritdoc * @public * @param {{ pattern?: Pattern, value?: Value }} [param0={}] * @param {Pattern} param0.pattern The pattern to sanitize the prefix. * @param {Value} param0.value The value of the prefix, constrained by the `string` type. * @returns {this} The current instance of `Prefix`. */ set({ pattern, value } = {}) { super.set({ pattern, value }); return this; } } // Class. /** * @description A class to manage suffixes that can be applied to strings. * @export * @class Suffix * @template {string} [Value=string] The type of suffix constrained by the `string`. * @template {RegExp | string | undefined} [Pattern=RegExp | string | undefined] The type of pattern constrained by the `RegExp` or `string`. * @extends {Affix<Value, 'suffix', Pattern>} */ class Suffix extends Affix { /** * @description Appends the suffix to the stem string. * @public * @static * @template {string} [Stem=string] The type of stem string constrained by the `string`. * @template {string} [Suffix=string] The type of suffix constrained by the `string`. * @param {Stem} stem The stem string to append the suffix. * @param {Suffix} [suffix=Suffix.default as Suffix] Suffix to append to stem. * @param {Delimiter} [delimiter='' as Delimiter] The delimiter to use between the stem and the suffix. * @param {boolean} [sanitize=true] Whether to sanitize the suffix using the static `Suffix.pattern`. * @returns {SuffixTemplate<Stem, Suffix>} */ static append(stem, suffix = Suffix.default, delimiter = '', sanitize = true) { return `${stem}${delimiter}${sanitize ? super.sanitize(suffix, this.pattern) : suffix}`; } /** * @description Tag name for the `toStringTag`. * @public * @static * @type {string} */ static tagName = 'Suffix'; /** * @description The default suffix to use. * @public * @static * @type {string} */ static default = ''; /** * @description Returns the `string` tag representation of the `Suffix` class when used in `Object.prototype.toString.call(instance)`. * @public * @readonly * @type {string} */ get [Symbol.toStringTag]() { return Suffix.tagName; } /** * @description The suffix value of generic type variable `Value` constrained by the `string` type. * @public * @readonly * @type {Value} */ get suffix() { return this.value; } /** * Creates an instance of `Suffix`. * @constructor * @param {Value} [value='' as Value] The value of the suffix, constrained by the `string` type. Defaults to an empty string. * @param {(Pattern)} [pattern=Suffix.pattern] The pattern to sanitize the suffix. Defaults to the static `Suffix.pattern`. */ constructor(value = '', pattern = Suffix.pattern) { super(value, { kind: 'suffix', pattern }); } /** * @description Appends the internal suffix to the stem string. * @public * @template {string} Stem The type of stem string. * @param {Stem} stem The stem string to append the suffix. * @param {Delimiter} delimiter The delimiter between stem and suffix. * @returns {SuffixTemplate<Stem, Value, Delimiter>} The returned value is a template of stem and suffix. */ appendTo(stem, delimiter = '') { return Suffix.append(stem, Suffix.sanitize(this.suffix, this.pattern), delimiter, false); } /** * Sets the pattern and value for the suffix affix. * @inheritdoc * @public * @param {{ pattern?: Pattern, value?: Value }} [param0={}] * @param {Pattern} param0.pattern The pattern to sanitize the suffix. * @param {Value} param0.value The value of the suffix, constrained by the `string` type. * @returns {this} The current instance of `Suffix`. */ set({ pattern, value } = {}) { super.set({ pattern, value }); return this; } } // Abstract. /* * Public API Surface of affix */ /** * Generated bundle index. Do not edit. */ export { Affix, AffixCore, Circumfix, Infix, Prefix, Suffix }; //# sourceMappingURL=typescript-package-affix.mjs.map