', #closing: '>', #opening: '<', #text: 'div'}
+
+console.log(htmlTag.valueOf()); // Output:
+
+// Initialize.
+const bbCode = new Wrapper('[', ']', 'quote');
+
+console.log(bbCode); // Output: Wrapper {'[quote]', #closing: ']', #opening: '[', #text: 'quote'}
+
+// Wrap the valueOf [quote]
+console.log(bbCode.wrap()); // Output: [[quote]]
+
+// Wrap the valueOf [quote] with the specified `opening` and `closing` chars.
+console.log(bbCode.wrap(`(`, `)`)); // Output: ([quote])
+
+// Wrap the specified text with the `opening` and `closing` chars.
+console.log(bbCode.wrapOn(`/italic`)); // Output: [/italic]
+
+// Replace the `opening` and `closing` chars.
+console.log(bbCode.rewrap(`(`, `)`)); // Output: (quote)
+
+// Wraps the `text` inside.
+console.log(bbCode.wrapText(`(`, `)`)); // Output: [(quote)]
+
+// Returns the primitive value.
+console.log(bbCode.valueOf()); // Output: [quote]
+```
+
+## GIT
+
+### Commit
+
+* [AngularJS Git Commit Message Conventions][git-commit-angular]
+* [Karma Git Commit Msg][git-commit-karma]
+* [Conventional Commits][git-commit-conventional]
+
+### Versioning
+
+[Semantic Versioning 2.0.0][git-semver]
+
+**Given a version number MAJOR.MINOR.PATCH, increment the:**
+
+* MAJOR version when you make incompatible API changes,
+* MINOR version when you add functionality in a backwards-compatible manner, and
+* PATCH version when you make backwards-compatible bug fixes.
+
+Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
+
+**FAQ**
+How should I deal with revisions in the 0.y.z initial development phase?
+
+> The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.
+
+How do I know when to release 1.0.0?
+
+> If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0.
+
+## License
+
+MIT © typescript-package ([license][typescript-package-license])
+
+
+
+ [typescript-package-badge-issues]: https://img.shields.io/github/issues/typescript-package/wrapper
+ [isscript-package-badge-forks]: https://img.shields.io/github/forks/typescript-package/wrapper
+ [typescript-package-badge-stars]: https://img.shields.io/github/stars/typescript-package/wrapper
+ [typescript-package-badge-license]: https://img.shields.io/github/license/typescript-package/wrapper
+
+ [typescript-package-issues]: https://github.com/typescript-package/wrapper/issues
+ [typescript-package-forks]: https://github.com/typescript-package/wrapper/network
+ [typescript-package-license]: https://github.com/typescript-package/wrapper/blob/master/LICENSE
+ [typescript-package-stars]: https://github.com/typescript-package/wrapper/stargazers
+
+
+
+
+ [typescript-package-npm-badge-svg]: https://badge.fury.io/js/@typescript-package%2Fwrapper.svg
+ [typescript-package-npm-badge]: https://badge.fury.io/js/@typescript-package%2Fwrapper
+
+
+[git-semver]: http://semver.org/
+
+
+[git-commit-angular]: https://gist.github.com/stephenparish/9941e89d80e2bc58a153
+[git-commit-karma]: http://karma-runner.github.io/0.10/dev/git-commit-msg.html
+[git-commit-conventional]: https://www.conventionalcommits.org/en/v1.0.0/
diff --git a/ng-package.json b/ng-package.json
new file mode 100644
index 0000000..af5858b
--- /dev/null
+++ b/ng-package.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
+ "dest": "../../dist/wrapper",
+ "lib": {
+ "entryFile": "src/public-api.ts"
+ },
+ "keepLifecycleScripts": true
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..e89b624
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,35 @@
+{
+ "name": "@typescript-package/wrapper",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@typescript-package/wrapper",
+ "version": "0.0.1",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://checkout.revolut.com/pay/048b10a3-0e10-42c8-a917-e3e9cb4c8e29"
+ }
+ ],
+ "license": "MIT",
+ "devDependencies": {
+ "@typescript-package/core": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-package/core": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@typescript-package/core/-/core-1.0.0.tgz",
+ "integrity": "sha512-HW+g5qCKbqDtoxCa+igceaZu2wWkw/YMw28VIXSz0hs7KUURHYtkAcuIG14VkOzaYgbgd1ZRBh4LzoVIp/DWVw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://checkout.revolut.com/pay/048b10a3-0e10-42c8-a917-e3e9cb4c8e29"
+ }
+ ],
+ "license": "MIT"
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..a275f53
--- /dev/null
+++ b/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "@typescript-package/wrapper",
+ "version": "0.0.1",
+ "author": "wwwdev.io
",
+ "description": "A lightweight TypeScript library to wrap the text with the opening and closing chars.",
+ "license": "MIT",
+ "publishConfig": {
+ "access": "public",
+ "registry": "https://registry.npmjs.org"
+ },
+ "devDependencies": {
+ "@typescript-package/core": "^1.0.0"
+ },
+ "scripts": {
+ "prepublishOnly": "npm run pkg && npm run clean",
+ "pkg": "npm pkg delete dependencies",
+ "clean": "npm pkg delete scripts"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/typescript-package/wrapper.git"
+ },
+ "bugs": {
+ "url": "https://github.com/typescript-package/wrapper/issues"
+ },
+ "keywords": [
+ "@typescript-package",
+ "@typescript-package/wrapper",
+ "Opening characters",
+ "Closing characters",
+ "Text",
+ "Wrap",
+ "Wrapper"
+ ],
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://checkout.revolut.com/pay/048b10a3-0e10-42c8-a917-e3e9cb4c8e29"
+ }
+ ],
+ "sideEffects": false
+}
diff --git a/src/lib/index.ts b/src/lib/index.ts
new file mode 100644
index 0000000..53821c8
--- /dev/null
+++ b/src/lib/index.ts
@@ -0,0 +1,2 @@
+export { Wrap } from './wrap.class';
+export { Wrapper } from './wrapper.class';
diff --git a/src/lib/wrap.class.ts b/src/lib/wrap.class.ts
new file mode 100644
index 0000000..44bf872
--- /dev/null
+++ b/src/lib/wrap.class.ts
@@ -0,0 +1,294 @@
+/**
+ * The `Wrap` object is based on the `String` object and represents the immutable primitive value of the text wrapped by the opening and
+ * closing chars. It is designed to preserve the type names of the supplied opening, text, and closing chars by using the generic type
+ * variables.
+ */
+export class Wrap<
+ Opening extends string = string,
+ Text extends string = '',
+ Closing extends string = string
+> extends String {
+ // #region instance public accessors.
+ /**
+ * The `get` accessor gets the closing of the wrap by returning the `#closing` property of a specified object.
+ * @returns The return value is closing of the wrap of a generic type variable `Closing`.
+ */
+ public get closing(): Closing {
+ return this.#closing;
+ }
+
+ /**
+ * The `get` accessor gets the opening of the wrap by returning the `#opening` property of a specified object.
+ * @returns The return value is the opening of the wrap of a generic type variable `Opening`.
+ */
+ public get opening(): Opening {
+ return this.#opening;
+ }
+
+ /**
+ * The `get` accessor gets the text of the `Wrap` by returning the `#text` property of a specified object.
+ * @returns The return value is the text of a generic type variable `Text`.
+ */
+ public get text(): Text {
+ return this.#text;
+ }
+
+ /**
+ * The `get` accessor, with the help of `toStringTag`, changes the default tag to `Wrap` for an instance of `Wrap`. It can be read by
+ * the `typeOf()` function of `@typescript-package/type`.
+ * @returns The return value is the word 'Wrap` of a `string`.
+ */
+ public get [Symbol.toStringTag](): string {
+ return 'Wrap';
+ }
+ //#endregion instance public accessors.
+
+ //#region instance private properties.
+ /**
+ * Private property of the closing chars of a generic type variable `Closing`.
+ */
+ #closing: Closing;
+
+ /**
+ * Private property of the opening chars of a generic type variable `Opening`.
+ */
+ #opening: Opening;
+
+ /**
+ * Private property of text of a generic type variable `Text`.
+ */
+ #text: Text;
+ //#endregion instance private properties.
+
+ //#region static public methods.
+ /**
+ * The method checks whether the text has given `closing` chars at the end.
+ * @param text The text of `string` type, to check whether it contains given `closing` chars.
+ * @param closing The closing chars of `string` type to check if a given `text` contains.
+ * @returns The return value is a `boolean` indicating whether the `text` contains `closing` chars at the end.
+ */
+ public static hasClosing(text: string, closing: string): boolean {
+ return (
+ typeof text === 'string' &&
+ text.length >= 1 &&
+ typeof closing === 'string' &&
+ closing.length >= 1 &&
+ text.slice(-closing.length) === closing
+ );
+ }
+
+ /**
+ * Checks whether the text has `opening` chars at the beginning.
+ * @param text The text of `string`, to check whether it contains given `opening` chars.
+ * @param opening The opening chars of `string` to check if a given `text` contains.
+ * @returns The return value is a `boolean` indicating whether the `text` contains `opening` chars at the beginning.
+ */
+ public static hasOpening(text: string, opening: string): boolean {
+ return (
+ typeof text === 'string' &&
+ text.length >= 1 &&
+ typeof opening === 'string' &&
+ opening.length >= 1 &&
+ text.slice(0, opening.length) === opening
+ );
+ }
+
+ /**
+ * The method checks whether the `value` of any type is the `Wrap` instance of any or given `opening` and `closing` chars.
+ * @param value The value of any type to test against the `Wrap` instance of any or given opening and closing.
+ * @param opening Optional opening chars of a generic type variable `Opening` to check if the given `value` contains.
+ * @param closing Optional closing chars of a generic type variable `Closing` to check if the given `value` contains.
+ * @param text An optional text of a generic type variable `Text` to check if the given `value` contains.
+ * @returns The return value is a `boolean` type indicating whether the value is an instance of `Wrap` of any, or the given opening,
+ * closing, and text.
+ */
+ public static isWrap<
+ Opening extends string = string,
+ Closing extends string = string,
+ Text extends string = ``
+ >(
+ value: any,
+ opening?: Opening,
+ closing?: Closing,
+ text?: Text
+ ): value is Wrap {
+ return typeof value === 'object' && value instanceof this
+ ? (typeof opening === 'string' ? opening === value.opening : true) &&
+ (typeof closing === 'string' ? closing === value.closing : true) &&
+ (typeof text === 'string' ? text === value.text : true)
+ : false;
+ }
+ //#endregion static public methods.
+
+ //#region constructor.
+ /**
+ * Creates a new `Wrap` instance of the opening and closing chars and optional text to wrap.
+ * @param opening Opening characters of the generic type variable `Opening` placed before the given `text`. An empty `string` indicates
+ * that for the `hasOpening()` and `isWrapped()` methods, the opening chars are `undefined`, returning `false`.
+ * @param closing Closing characters of the generic type variable `Closing` placed after the given `text`. An empty `string` indicates
+ * that for the `hasClosing()` and `isWrapped()` methods, the closing chars are `undefined`, returning `false`.
+ * @param text An optional text placed between the given `opening` and `closing` chars on the template `${Opening}${Text}${Closing}`.
+ */
+ constructor(opening: Opening, closing: Closing, text: Text = '' as Text) {
+ super(`${opening}${text}${closing}`);
+ this.#closing = String(closing) as Closing;
+ this.#text = String(text) as Text;
+ this.#opening = String(opening) as Opening;
+ }
+ //#endregion constructor.
+
+ //#region instance public methods.
+ /**
+ * Gets the closing chars of the wrap by returning the `#closing` property of a specified object.
+ * @returns The return value is closing chars of a generic type variable `Closing`.
+ */
+ public getClosing(): Closing {
+ return this.#closing;
+ }
+
+ /**
+ * Gets the opening chars of the wrap by returning the `#opening` property of a specified object.
+ * @returns The return value is opening chars of a generic type variable `Opening`.
+ */
+ public getOpening(): Opening {
+ return this.#opening;
+ }
+
+ /**
+ * Gets the text of the wrap by returning the `#text` property of a specified object, without the opening and closing chars of the `Wrap`.
+ * @returns The return value is the text of a generic type variable `Text`.
+ */
+ public getText(): Text {
+ return this.#text;
+ }
+
+ /**
+ * Checks whether the primitive value of a specified object has the closing chars or given `closing` chars. If given `closing` chars in
+ * the constructor are the empty `string`, the method returns `false`.
+ * @param closing Optional closing chars of a `string` type to check whether the primitive value contains them at the **end**.
+ * @returns The return value is a `boolean` indicating whether the primitive value has the closing chars or given closing chars.
+ */
+ public hasClosing(closing?: string): boolean {
+ return (
+ this.#closing.length >= 1 &&
+ (typeof closing === 'string' ? this.#closing === closing : true)
+ );
+ }
+
+ /**
+ * Checks whether the primitive value of a specified object has the opening chars or given `opening` chars. If given `opening` chars in
+ * the constructor are the empty `string`, the method returns `false`.
+ * @param opening Optional opening chars of a `string` type to check if the primitive value contains them at the **beginning**.
+ * @returns The return value is a `boolean` indicating whether the primitive value has the opening chars or given `opening` chars.
+ */
+ public hasOpening(opening?: string): boolean {
+ return (
+ this.#opening.length >= 1 &&
+ (typeof opening === 'string' ? this.#opening === opening : true)
+ );
+ }
+
+ /**
+ * The method checks whether the text of a specified `Wrap` object is defined, which means it's a `string` of at least one char and
+ * optionally equal to the given `text`.
+ * @param text Optional text of `string` type to check whether it's equal to the text of the `Wrap` object.
+ * @returns The return value is a `boolean` indicating whether the text is defined and optionally equal to the given text.
+ */
+ public hasText(text?: string): boolean {
+ return (
+ this.#text.length >= 1 &&
+ (typeof text === 'string' ? this.#text === text : true)
+ );
+ }
+
+ /**
+ * The method checks whether the primitive value of the specified `object` is wrapped by the opening and closing chars of an instance or
+ * given `opening` and `closing` chars. If given `opening` or `closing` chars in the constructor are the empty `string`, the method
+ * returns `false`.
+ * @param opening Optional opening chars of a `string` type to check if the primitive value contains them at the beginning. The default
+ * value is picked from the private `#opening` property of an instance.
+ * @param closing Optional closing chars of a `string` type to check if the primitive value contains them at the end. The default value is
+ * picked from the private `#closing` property of an instance.
+ * @returns The return value is a `boolean` indicating whether the object has both opening and closing chars or given `opening` and
+ * `closing` chars.
+ */
+ public isWrapped(
+ opening: string = this.#opening,
+ closing: string = this.#closing
+ ): boolean {
+ return this.hasOpening(opening) && this.hasClosing(closing);
+ }
+
+ /**
+ * Returns the primitive value with replaced closing chars.
+ * @param closing The closing chars of a generic type variable `ReplaceClosing` to replace the closing chars in the primitive value.
+ * @returns The return value is the primitive value with replaced closing chars of a generic type variables in order `Opening`, `Text` and
+ * `ReplaceClosing` on the template `${Opening}${Text}${ReplaceClosing}`.
+ */
+ public replaceClosing(
+ closing: ReplaceClosing
+ ): `${Opening}${Text}${ReplaceClosing}` {
+ return `${this.#opening}${this.#text}${closing}`;
+ }
+
+ /**
+ * Returns the primitive value with replaced opening chars.
+ * @param opening The opening chars of a generic type variable `ReplaceOpening` to replace the opening chars in the primitive value.
+ * @returns The return value is the primitive value with replaced opening chars of a generic type variables in order `ReplaceOpening`,
+ * `Text` and `Closing` on the template `${ReplaceOpening}${Text}${Closing}`.
+ */
+ public replaceOpening(
+ opening: ReplaceOpening
+ ): `${ReplaceOpening}${Text}${Closing}` {
+ return `${opening}${this.#text}${this.#closing}`;
+ }
+
+ /**
+ * Returns the primitive value with replaced text.
+ * @param text The text of a generic type variable `ReplaceText` to replace the text in the primitive value.
+ * @returns The return value is the primitive value with replaced text of a generic type variables in order `Opening`, `ReplaceText`
+ * and `Closing` on the template `${Opening}${ReplaceText}${Closing}`.
+ */
+ public replaceText(
+ text: ReplaceText
+ ): `${Opening}${ReplaceText}${Closing}` {
+ return `${this.#opening}${text}${this.#closing}`;
+ }
+
+ /**
+ * Checks whether the wrapped text starts with the specified opening characters.
+ * @param opening Optional opening characters to check against. Defaults to the instance's `#opening`.
+ * @returns The returned value is a `boolean` indicating whether the wrapped text starts with the given or default opening characters.
+ */
+ public override startsWith(opening: string = this.#opening): boolean {
+ return this.toString().startsWith(opening);
+ }
+
+ /**
+ * Checks whether the wrapped text ends with the specified closing characters.
+ * @param closing Optional closing characters to check against. Defaults to the instance's `#closing`.
+ * @returns The returned value is a `boolean` indicating whether the wrapped text ends with the given or default closing characters.
+ */
+ public override endsWith(closing: string = this.#closing): boolean {
+ return this.toString().endsWith(closing);
+ }
+
+ /**
+ * Gets the wrap, the primitive value of a specified `Wrap` object.
+ * @returns The return value is the wrap of generic type variables in order `Opening`, `Text`, and `Closing` on the template
+ * `${Opening}${Text}${Closing}`.
+ */
+ public override toString(): `${Opening}${Text}${Closing}` {
+ return super.toString() as `${Opening}${Text}${Closing}`;
+ }
+
+ /**
+ * Returns the wrap, primitive value of a specified `Wrap` object.
+ * @returns The return value is the wrap of generic type variables in order `Opening`, `Text`, and `Closing` on the template
+ * `${Opening}${Text}${Closing}`.
+ */
+ public override valueOf(): `${Opening}${Text}${Closing}` {
+ return super.valueOf() as `${Opening}${Text}${Closing}`;
+ }
+ //#endregion instance public methods.
+}
diff --git a/src/lib/wrapper.class.ts b/src/lib/wrapper.class.ts
new file mode 100644
index 0000000..e8282de
--- /dev/null
+++ b/src/lib/wrapper.class.ts
@@ -0,0 +1,330 @@
+// Class.
+import { Wrap } from './wrap.class';
+// Type.
+import { Wrapped } from '../type/wrapped.type';
+/**
+ * The `Wrapper` is an extension of the `Wrap` object, which means it represents the immutable wrap of the opening and closing with the
+ * additional ability to use it to wrap strings.
+ */
+export class Wrapper<
+ Opening extends string = string,
+ Text extends string = '',
+ Closing extends string = string
+> extends Wrap {
+ //#region instance accessors.
+ /**
+ * The property, with the help of `toStringTag`, changes the default tag to `Wrapper` in the `Wrapper` instance. It can be read by the
+ * `typeOf()` function of `@angular-package/type`.
+ */
+ public override get [Symbol.toStringTag](): string {
+ return 'Wrapper';
+ }
+ //#endregion instance accessors.
+
+ //#region static public methods.
+ /**
+ * Defines a new `Wrapper` instance with the provided `opening`, `closing` chars, and optional `text`.
+ * @param opening The opening chars of generic type variable `Opening` for new `Wrapper` instance.
+ * @param closing The closing chars of generic type variable `Closing` for new `Wrapper` instance.
+ * @param text An optional text of generic type variable `Text` for new `Wrapper` instance.
+ * @returns The return value is the `Wrapper` instance of given `opening`, `closing` chars, and optional `text`.
+ */
+ public static define<
+ Opening extends string,
+ Closing extends string,
+ Text extends string = ''
+ >(
+ opening: Opening,
+ closing: Closing,
+ text?: Text
+ ): Wrapper {
+ return new this(opening, closing, text);
+ }
+
+ /**
+ * The method checks if the value of any type is an instance of the `Wrapper` of any, or the given `opening`, `closing` chars, and `text`.
+ * @param value The value of any type to test against the `Wrapper` instance.
+ * @param opening Optional opening chars of generic type variable `Opening` to check if the given `value` contains.
+ * @param closing Optional closing chars of generic type variable `Closing` to check if the given `value` contains.
+ * @param text An optional text of generic type variable `Text` to check if the given `value` contains.
+ * @returns The return value is a `boolean` type indicating whether the value is an instance of `Wrapper` of any, or the given opening,
+ * closing chars, and text.
+ */
+ public static isWrapper<
+ Opening extends string,
+ Closing extends string,
+ Text extends string = string
+ >(
+ value: any,
+ opening?: Opening,
+ closing?: Closing,
+ text?: Text
+ ): value is Wrapper {
+ return (
+ typeof value === 'object' &&
+ value instanceof this &&
+ super.isWrap(value, opening, closing, text)
+ );
+ }
+
+ /**
+ * Replaces given `closing` chars with a given replacement value at the end of the given `text`.
+ * @param text The text of `string` type in which given `closing` characters are replaced by a given replacement value.
+ * @param closing The closing chars of the `string` to replace by a given replacement value at the end of the given `text`.
+ * @param replacement The replacement value of a string type for the given `closing` characters in the given `text`.
+ * @returns The return value is the given `text` of `string` type with a replaced `closing` chars by a given replacement value or the
+ * specified `text` unchanged if it does not contain the given `closing` chars.
+ */
+ public static replaceClosing(
+ text: string,
+ closing: string,
+ replacement: string
+ ): string {
+ return this.hasClosing(text, closing)
+ ? text.slice(0, -closing.length) + replacement
+ : text;
+ }
+
+ /**
+ * Replaces given `opening` chars with a given replacement value at the beginning of the given `text`.
+ * @param text The text of `string` type in which the given `opening` chars are replaced by a given replacement value.
+ * @param opening The opening chars of the `string` to replace by a given replacement value at the beginning of the given `text`.
+ * @param replacement The replacement value of a string type for the given `opening` characters in the given `text`.
+ * @returns The return value is the given `text` of `string` type with a replaced `opening` chars by a given replacement value or the
+ * specified `text` unchanged if it does not contain the given `opening` chars.
+ */
+ public static replaceOpening(
+ text: string,
+ opening: string,
+ replacement: string
+ ): string {
+ return this.hasOpening(text, opening)
+ ? text.replace(opening, String(replacement))
+ : text;
+ }
+
+ /**
+ * The method returns the given `text` without the given `opening` and `closing` chars.
+ * @param text The text of the `string` from which given opening and closing chars are removed.
+ * @param opening The opening chars of the `string` to be removed in the given `text`.
+ * @param closing The closing chars of the `string` to be removed in the given `text`.
+ * @returns The return value is the given `text` of `string` type without the given `opening` and `closing` chars or unchanged `text` if
+ * it does not contain the given `opening` and `closing` chars.
+ */
+ public static unwrap(text: string, opening: string, closing: string): string {
+ return (
+ (text = this.replaceClosing(text, closing, '')),
+ (text = this.replaceOpening(text, opening, '')),
+ text
+ );
+ }
+ //#endregion static public methods.
+
+ //#region constructor.
+ /**
+ * Creates a new `Wrapper` instance with the opening and closing chars and optional text.
+ * @param opening The opening chars of a generic type variable `Opening` placed before the given `text`.
+ * @param closing The closing chars of a generic type variable `Closing` placed after the given `text`.
+ * @param text Optional text of a generic type variable `Text` to wrap by given `opening` and `closing` chars.
+ * @returns The return value is a new `Wrapper` instance.
+ */
+ constructor(opening: Opening, closing: Closing, text: Text = '' as Text) {
+ super(opening, closing, text);
+ }
+ //#endregion constructor.
+
+ //#region instance public methods.
+ /**
+ * Determines whether the provided `text` has the closing chars of the specified `Wrapper` object at the end.
+ * @param text The text of `string` to test for the existence of the closing chars at the end of it.
+ * @returns The return value is a `boolean` indicating whether the given `text` has the closing chars of the wrap.
+ */
+ public isClosingIn(text: string): boolean {
+ return Wrapper.hasClosing(text, this.closing);
+ }
+
+ /**
+ * Checks whether the provided `text` has the opening chars of a specified `Wrapper` object at the beginning.
+ * @param text The text of `string` to test for the existence of the opening chars at the beginning of it.
+ * @returns The return value is a `boolean` indicating whether the given `text` has the opening chars of the wrap.
+ */
+ public isOpeningIn(text: string): boolean {
+ return Wrapper.hasOpening(text, this.opening);
+ }
+
+ /**
+ * Replaces the closing chars of the `Wrapper` object in the given `text` with a given replacement value.
+ * The replacement succeeds if the closing characters exist at the end of the text.
+ * @param text The text of `string` type in which the closing chars are replaced by given replacement value.
+ * @param replaceValue The value of `string` type as a replacement for the closing chars at the end of the given `text`.
+ * @returns The return value is the given `text` of `string` type with replaced closing chars by given replacement value.
+ */
+ public replaceClosingIn(text: string, replaceValue: string): string {
+ return Wrapper.replaceClosing(text, this.closing, replaceValue);
+ }
+
+ /**
+ * Replaces the opening chars of the `Wrapper` object in the given `text` with a given replacement value.
+ * The replacement succeeds if the opening characters exist at the beginning of the text.
+ * @param text The text of `string` type in which the opening chars are replaced by given replacement value.
+ * @param replaceValue The value of `string` type as a replacement for the opening chars at the beginning of the given `text`.
+ * @returns The return value is the given `text` of `string` type with replaced opening chars by given replacement value.
+ */
+ public replaceOpeningIn(text: string, replaceValue: string): string {
+ return Wrapper.replaceOpening(text, this.opening, replaceValue);
+ }
+
+ /**
+ * Returns given `text` without the opening and closing chars of the `Wrapper` object.
+ * @param text The text of a `string` type to unwrap from the opening and closing chars of the `Wrapper` object.
+ * @returns The return value is the text of `string` type unwrapped from the opening and closing chars of the `Wrapper` object.
+ */
+ public removeWrapIn(text: string): string {
+ return (
+ (text = this.replaceClosingIn(text, '')),
+ (text = this.replaceOpeningIn(text, '')),
+ text
+ );
+ }
+
+ /**
+ * The method returns the text of the `Wrapper` object wrapped by the given `opening` and `closing` chars.
+ * @param opening The opening chars of a generic type variable `TextOpening` to wrap the text of the `Wrapper` instance.
+ * @param closing The closing chars of a generic type variable `TextClosing` to wrap the text of the `Wrapper` instance.
+ * @returns The return value is the text wrapped by given `opening` and closing `chars` of generic type `Wrapped`.
+ */
+ public rewrap(
+ opening: TextOpening,
+ closing: TextClosing
+ ): Wrapped {
+ return new Wrap(opening, closing, this.text).valueOf();
+ }
+
+ /**
+ * Replaces the closing chars of the `Wrapper` object in the text of the `Wrapper` object with the given `closing` chars.
+ * The replacement succeeds if the closing characters exist at the end of the text.
+ * @param closing The closing chars of `string` to replace in the text(part of the primitive value).
+ * @returns The return value is the text of `string` type with replaced closing chars.
+ */
+ public textReplaceClosing(closing: string): string {
+ return Wrapper.replaceClosing(this.text, this.closing, closing);
+ }
+
+ /**
+ * Replaces the opening chars of the `Wrapper` object in the text of the `Wrapper` object with the given `opening` chars. The replacement
+ * succeeds if the opening characters exist at the beginning of the text.
+ * @param opening The opening chars of `string` to replace in the text(part of the primitive value).
+ * @returns The return value is the text of `string` type with replaced opening chars.
+ */
+ public textReplaceOpening(opening: string): string {
+ return Wrapper.replaceOpening(this.text, this.opening, opening);
+ }
+
+ /**
+ * The method returns the text of the `Wrapper` object without its opening and closing chars or the given `opening` and `closing` chars.
+ * @param opening Optional opening chars of `string` type to remove from the beginning of the text of the `Wrapper` instance. By default,
+ * its value is equal to the opening chars of the `Wrapper` instance.
+ * @param closing Optional closing chars of `string` type to remove from the end of the text of the `Wrapper` instance. By default, its
+ * value is equal to the closing chars of the `Wrapper` instance.
+ * @returns The return value is the text of `string` type without the opening and closing chars of the `Wrapper` object or given `opening`
+ * and `closing` chars.
+ */
+ public textUnwrap(
+ opening: string = this.opening,
+ closing: string = this.closing
+ ): string {
+ return Wrapper.unwrap(this.text, opening, closing);
+ }
+
+ /**
+ * Returns an `array` consisting of the opening chars, text, and closing chars.
+ * @returns The return value is a read-only `array` consisting of the opening chars, text, and closing chars.
+ */
+ public toArray(): readonly [Opening, Text, Closing] {
+ return [this.opening, this.text, this.closing];
+ }
+
+ /**
+ * Returns the `Wrap` instance consists of the text, opening and closing chars of the `Wrapper` object.
+ * @returns The return value is an instance of `Wrap` consisting of the text, opening, and closing chars of the `Wrapper` object.
+ */
+ public toWrap(): Wrap {
+ return new Wrap(this.opening, this.closing, this.text);
+ }
+
+ /**
+ * Returns the text without the opening and closing chars.
+ * @returns The return value is the text of a generic type variable `Text`.
+ */
+ public unwrap(): Text {
+ return this.text;
+ }
+
+ /**
+ * The method returns the primitive value of a specified `Wrapper` object with text unwrapped from the opening and closing chars of the
+ * `Wrapper` instance or given `opening` and `closing` chars.
+ * @param opening Optional opening chars of `string` type to remove from the beginning of the text of the `Wrapper` instance. By default,
+ * its value is equal to the opening chars of the `Wrapper` instance.
+ * @param closing Optional closing chars of `string` type to remove from the end of the text of the `Wrapper` instance. By default, its
+ * value is equal to the closing chars of the `Wrapper` instance.
+ * @returns The return value is the primitive value of `string` type with text unwrapped from the opening and closing chars of the
+ * `Wrapper` object or the given `opening` and `closing` chars.
+ */
+ public unwrapText(
+ opening: string = this.opening,
+ closing: string = this.closing
+ ): string {
+ return `${this.opening}${Wrapper.unwrap(this.text, opening, closing)}${
+ this.closing
+ }`;
+ }
+
+ /**
+ * The method wraps the primitive value of a specified `Wrapper` object by its opening and closing chars or given `opening` and `closing`
+ * chars.
+ * @param opening Optional opening chars of a generic type variable `CustomOpening` to wrap the primitive value of the `Wrapper` instance.
+ * By default, its value is equal to the opening chars of the `Wrapper` instance.
+ * @param closing Optional closing chars of a generic type variable `CustomClosing` to wrap the primitive value of the `Wrapper` instance.
+ * By default, its value is equal to the closing chars of the `Wrapper` instance.
+ * @returns The return value is a primitive value wrapped by the opening and closing chars of the `Wrapper` instance or the given
+ * `opening` and `closing` chars.
+ */
+ public wrap<
+ CustomOpening extends string = Opening,
+ CustomClosing extends string = Closing
+ >(
+ opening: CustomOpening = this.opening as any,
+ closing: CustomClosing = this.closing as any
+ ): Wrapped, CustomClosing> {
+ return new Wrap(opening, closing, this.valueOf()).valueOf();
+ }
+
+ /**
+ * The method wraps the given `text` with the wrap, the `opening`, and `closing` chars of the `Wrapper` object.
+ * @param text The text of generic type variable `CustomText` to wrap by the opening and closing chars of the `Wrapper` instance.
+ * @returns The return value is the given `text` wrapped by the opening and closing chars of the `Wrapper` object of the generic type
+ * `Wrapped`.
+ */
+ public wrapOn(
+ text: CustomText
+ ): Wrapped {
+ return new Wrap(this.opening, this.closing, text).valueOf();
+ }
+
+ /**
+ * The method returns the primitive value of the `Wrapper` object with text wrapped by given `opening` and `closing` chars.
+ * @param opening The opening chars of a generic type variable `TextOpening` to wrap the text of the `Wrapper` instance.
+ * @param closing The closing chars of a generic type variable `TextClosing` to wrap the text of the `Wrapper` instance.
+ * @returns The return value is the primitive value with wrapped text by given opening and closing characters of generic type `Wrapped`.
+ */
+ public wrapText<
+ TextOpening extends string = '',
+ TextClosing extends string = ''
+ >(
+ opening: TextOpening,
+ closing: TextClosing
+ ): Wrapped, Closing> {
+ return `${this.opening}${this.rewrap(opening, closing)}${this.closing}`;
+ }
+ //#endregion instance public methods.
+}
diff --git a/src/public-api.ts b/src/public-api.ts
new file mode 100644
index 0000000..f2b2140
--- /dev/null
+++ b/src/public-api.ts
@@ -0,0 +1,11 @@
+/*
+ * Public API Surface of wrapper
+ */
+
+export {
+ // Object.
+ Wrap,
+ Wrapper,
+} from './lib';
+
+export type { Wrapped } from './type/wrapped.type';
diff --git a/src/test/wrap.spec.ts b/src/test/wrap.spec.ts
new file mode 100644
index 0000000..3af0dcb
--- /dev/null
+++ b/src/test/wrap.spec.ts
@@ -0,0 +1,20 @@
+import { Wrap } from "../lib";
+
+console.group(`Wrap`);
+
+// Initialize.
+const htmlTag = new Wrap('<', '>', 'div');
+
+// The `Wrap` object.
+console.log(htmlTag); // Output: Wrap {'', #closing: '>', #opening: '<', #text: 'div'}
+
+console.log(htmlTag.valueOf()); // Output:
+
+// Initialize.
+const bbCode = new Wrap('[', ']', 'quote');
+
+console.log(bbCode); // Output: Wrap {'[quote]', #closing: ']', #opening: '[', #text: 'quote'}
+
+console.log(bbCode.valueOf()); // Output: [quote]
+
+console.groupEnd();
diff --git a/src/test/wrapper.spec.ts b/src/test/wrapper.spec.ts
new file mode 100644
index 0000000..25c268b
--- /dev/null
+++ b/src/test/wrapper.spec.ts
@@ -0,0 +1,40 @@
+import { Wrapper } from "../lib";
+
+console.group(`Wrapper`);
+
+// Initialize.
+const htmlTag = new Wrapper(
+ '<',
+ '>',
+ 'div'
+);
+
+// The `Wrap` object.
+console.log(htmlTag); // Output: Wrapper {'
', #closing: '>', #opening: '<', #text: 'div'}
+
+console.log(htmlTag.valueOf()); // Output:
+
+// Initialize.
+const bbCode = new Wrapper('[', ']', 'quote');
+
+console.log(bbCode); // Output: Wrapper {'[quote]', #closing: ']', #opening: '[', #text: 'quote'}
+
+// Wrap the valueOf [quote]
+console.log(bbCode.wrap()); // Output: [[quote]]
+
+// Wrap the valueOf [quote] with the specified `opening` and `closing` chars.
+console.log(bbCode.wrap(`(`, `)`)); // Output: ([quote])
+
+// Wrap the specified text with the `opening` and `closing` chars.
+console.log(bbCode.wrapOn(`/italic`)); // Output: [/italic]
+
+// Replace the `opening` and `closing` chars.
+console.log(bbCode.rewrap(`(`, `)`)); // Output: (quote)
+
+// Wraps the `text` inside.
+console.log(bbCode.wrapText(`(`, `)`)); // Output: [(quote)]
+
+// Returns the primitive value.
+console.log(bbCode.valueOf()); // Output: [quote]
+
+console.groupEnd();
diff --git a/src/type/wrapped.type.ts b/src/type/wrapped.type.ts
new file mode 100644
index 0000000..2f1dbd8
--- /dev/null
+++ b/src/type/wrapped.type.ts
@@ -0,0 +1,10 @@
+/**
+ * The `Wrapped` type indicates the text wrapped by the opening characters at the beginning and the closing characters at the end of the
+ * text.
+ * It's built from generic type variables in order `Opening`, `Text` and `Closing` on the template `${Opening}${Text}${Closing}`.
+ */
+export type Wrapped<
+ Opening extends string = '',
+ Text extends string = '',
+ Closing extends string = ''
+> = `${Opening}${Text}${Closing}`;
diff --git a/tsconfig.lib.json b/tsconfig.lib.json
new file mode 100644
index 0000000..2359bf6
--- /dev/null
+++ b/tsconfig.lib.json
@@ -0,0 +1,15 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../out-tsc/lib",
+ "declaration": true,
+ "declarationMap": true,
+ "inlineSources": true,
+ "types": []
+ },
+ "exclude": [
+ "**/*.spec.ts"
+ ]
+}
diff --git a/tsconfig.lib.prod.json b/tsconfig.lib.prod.json
new file mode 100644
index 0000000..9215caa
--- /dev/null
+++ b/tsconfig.lib.prod.json
@@ -0,0 +1,11 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+ "extends": "./tsconfig.lib.json",
+ "compilerOptions": {
+ "declarationMap": false
+ },
+ "angularCompilerOptions": {
+ "compilationMode": "partial"
+ }
+}
diff --git a/tsconfig.spec.json b/tsconfig.spec.json
new file mode 100644
index 0000000..254686d
--- /dev/null
+++ b/tsconfig.spec.json
@@ -0,0 +1,15 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../out-tsc/spec",
+ "types": [
+ "jasmine"
+ ]
+ },
+ "include": [
+ "**/*.spec.ts",
+ "**/*.d.ts"
+ ]
+}