diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3a501b0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 100 + +[*.yml] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..94f480d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a6e38df --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + ignore: + # For all packages, ignore all patch updates + - dependency-name: "*" + update-types: ["version-update:semver-major"] + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..a768beb --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,22 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Node.js ${{ matrix.node-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: + - 21 + - 20 + - 18 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..18a369a --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,28 @@ +name: Publish Package to npmjs +on: + release: + types: [published] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20.x" + - run: npm i + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20.x" + registry-url: "https://registry.npmjs.org" + - run: npm i + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..58e33a4 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,21 @@ +name: Mark Stale Issues and PR +on: + schedule: + - cron: "*/10 5 * * *" +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-stale: 365 + stale-issue-message: "This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days." + stale-pr-message: "This PR is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days." + close-issue-message: "This issue was closed because it has been stalled for 7 days with no activity." + close-pr-message: "This PR was closed because it has been stalled for 7 days with no activity." + exempt-issue-labels: "Help Wanted, Good first issue, Never gets stale" + exempt-pr-labels: "Help Wanted, Never gets stale" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..129766d --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +node_modules/ +*.log +dist +.nyc_output + +# Ignore test-related files +/coverage.data +/coverage/ + +# Ignore build package +*.tgz +package/ + +.vscode/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..9cf9495 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b51eecc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Palash Mondal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..37166e1 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# hyphen-sanitizer + +> Simplifying text by replacing hyphens with ease + +![CI](https://github.com/palashmon/hyphen-sanitizer/actions/workflows/main.yml/badge.svg) +[![npm version](https://img.shields.io/npm/v/hyphen-sanitizer.svg)](http://npm.im/hyphen-sanitizer) +[![npm downloads](https://img.shields.io/npm/dm/hyphen-sanitizer.svg)](http://npm.im/hyphen-sanitizer) + +Hyphens are commonly used in strings to separate words or denote compound words. However, in certain scenarios, it's necessary to sanitize hyphens by replacing them with another character or removing them entirely. `hyphen-sanitizer` provides a simple yet powerful solution for sanitizing hyphens within strings, enhancing data consistency and usability. + +### Key Features + +- Sanitizes hyphens within strings +- Allows customization of replacement string +- Defaults to space if no replacement string is provided +- Versatile and easy to integrate into existing projects + +## Install + +```sh +npm install hyphen-sanitizer +``` + +## Usage + +```js +import hyphenSanitizer from "hyphen-sanitizer"; + +// Example 1 - Default replacement +// Replaces hyphens with spaces +const text = "Hello-world"; +const sanitizedText = hyphenSanitizer(text); +console.log(sanitizedText); //=> "Hello world" + +// Example 2 - Custom replacement +// Replaces hyphens with underscores +const replacement = "_"; +const sanitizedText2 = hyphenSanitizer(text, replacement); +console.log(sanitizedText2); //=> "Hello_world" +``` + +## API + +### hyphenSanitizer(input, replacement) + +#### input + +Type: `string` + +The input string to sanitize. This string may contain hyphens that need to be replaced. + +#### replacement + +Type: `string`
+Default: `' '` (space) + +The replacement string to use in place of hyphens. If no replacement string is provided, hyphens will be replaced with spaces. + +## Related + +- [acronymer](https://github.com/palashmon/acronymer) - Generate acronyms from strings + +## License + +MIT © [Palash Mondal](https://github.com/palashmon) diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..e24d84f --- /dev/null +++ b/index.d.ts @@ -0,0 +1,25 @@ +/** +Replaces hyphens in a given text with a specified replacement string. + +@param {string} text - The input text to sanitize. +@param {string} [replacement=" "] - The replacement string for hyphens. Defaults to a space. +@returns {string} The sanitized string with hyphens replaced by the specified replacement string. +@throws {TypeError} If the input value is not a string or if the replacement is not a string. + +@example +``` +import hyphenSanitizer from "hyphen-sanitizer"; + +const text = "Hello-world"; + +// Replaces hyphens with spaces +const sanitizedText = hyphenSanitizer(text); +console.log(sanitizedText); //=> "Hello world" + +// Replaces hyphens with underscores +const replacement = "_"; +const sanitizedText2 = hyphenSanitizer(text, replacement); +console.log(sanitizedText2); //=> "Hello_world" +``` +*/ +export default function hyphenSanitizer(text: string, replacement?: string): string; diff --git a/index.js b/index.js new file mode 100644 index 0000000..b3373de --- /dev/null +++ b/index.js @@ -0,0 +1,14 @@ +export default function hyphenSanitizer(text, replacement = ' ') { + if (typeof text !== 'string') { + throw new TypeError('Input value must be a string.'); + } + + if (typeof replacement !== 'string') { + throw new TypeError('Replacement must be a string.'); + } + + const hyphenRegex = /-/g; + /** @type {string} */ + const sanitizedString = text.replaceAll(hyphenRegex, replacement); + return sanitizedString; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..122294b --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "hyphen-sanitizer", + "version": "0.1.0", + "description": "Simplifying text by replacing hyphens with ease", + "license": "MIT", + "repository": "palashmon/hyphen-sanitizer", + "author": "Palash Mondal ", + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "scripts": { + "test": "xo && ava", + "lint": "xo --fix" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "alter", + "code", + "convert", + "edit", + "format", + "function", + "hyphen", + "javascript", + "library", + "modify", + "modifystring", + "replace", + "replacehyphen", + "sanitize", + "sanitizer", + "string", + "strings", + "substitute", + "text", + "tool", + "transform", + "utility" + ], + "devDependencies": { + "ava": "^6.0.0", + "xo": "^0.56.0" + } +} diff --git a/test.js b/test.js new file mode 100644 index 0000000..40bc326 --- /dev/null +++ b/test.js @@ -0,0 +1,38 @@ +import test from 'ava'; +import hyphenSanitizer from './index.js'; + +test('Replace hyphens with spaces by default', t => { + const originalString = 'This-is-a-sample-string'; + const expectedString = 'This is a sample string'; + t.is(hyphenSanitizer(originalString), expectedString); +}); + +test('Replace hyphens with a custom string', t => { + const originalString = 'This-is-a-sample-string'; + const expectedString = 'This_is_a_sample_string'; + const customReplacement = '_'; + t.is(hyphenSanitizer(originalString, customReplacement), expectedString); +}); + +test('Return empty string for empty input string', t => { + const originalString = ''; + const expectedString = ''; + t.is(hyphenSanitizer(originalString), expectedString); +}); + +test('Throw error for non-string input', t => { + const invalidInput = 123; // Non-string input + const error = t.throws(() => { + hyphenSanitizer(invalidInput); + }, {instanceOf: TypeError}); + t.is(error.message, 'Input value must be a string.'); +}); + +test('Throw error for non-string replacement', t => { + const originalString = 'This-is-a-sample-string'; + const invalidReplacement = 123; // Non-string replacement + const error = t.throws(() => { + hyphenSanitizer(originalString, invalidReplacement); + }, {instanceOf: TypeError}); + t.is(error.message, 'Replacement must be a string.'); +});