
# Security Words Picker

![License: NIGGALINKAI](https://img.shields.io/badge/License-NIGGALINKAI-yellow.svg)
![npm](https://img.shields.io/npm/v/security-words-picker)
![Node.js](https://img.shields.io/badge/node-%3E%3D%2014.0.0-blue.svg)
![Size](https://img.shields.io/bundlephobia/min/security-words-picker)

**Security Words Picker** is a fun and easy tool that helps you pick words from a big list of over **20,000+ words**. Whether you're making games, creating secure passwords, or just having fun with words, this package has got you covered!

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
  - [Example 1: Pick 5 Random Words](#example-1-pick-5-random-words)
  - [Example 2: Pick Words of a Certain Length](#example-2-pick-words-of-a-certain-length)
  - [Example 3: Pick Words That Start or End With Specific Letters](#example-3-pick-words-that-start-or-end-with-specific-letters)
  - [Example 4: Get Words as a Sentence](#example-4-get-words-as-a-sentence)
  - [Example 5: Sort Words and Change Their Case](#example-5-sort-words-and-change-their-case)
- [API Reference](#api-reference)
  - [getWords(options, amountOfWords, wordsArray)](#getwordoptions-number-amountofwords-array-wordsarray)
- [Options](#options)
- [Contributing](#contributing)
- [License](#license)
- [Acknowledgments](#acknowledgments)

## Features

**Security Words Picker** is packed with cool features to make picking words super easy and fun:

1. **Pick Words by Length**
   - **What it does:** Choose words that are not too short or too long.
   - **Example:** Pick words that are at least 5 letters and no more than 10 letters.
   - **How to use:**
     ```javascript
     const options = {
       lengthMin: 5,
       lengthMax: 10
     };
     const words = getWords(options, 10, wordsArray);
     console.log(words);
     // Output: ["apple", "banana", "cherry", ...]
     ```

2. **Pick Random Words**
   - **What it does:** Get a random set of words from the list.
   - **Example:** Pick 5 random words.
   - **How to use:**
     ```javascript
     const words = getWords({}, 5, wordsArray);
     console.log(words);
     // Output: ["sun", "moon", "star", "cloud", "rain"]
     ```

3. **Start or End With Specific Letters**
   - **What it does:** Choose words that start or end with certain letters.
   - **Example:** Pick words that start with "a" or end with "ing".
   - **How to use:**
     ```javascript
     const options = {
       filterStartsWith: ["a"],
       filterEndsWith: ["ing"]
     };
     const words = getWords(options, 6, wordsArray);
     console.log(words);
     // Output: ["acting", "asking", "acing", ...]
     ```

4. **Exclude Certain Words**
   - **What it does:** Avoid words that have specific letters or patterns.
   - **Example:** Exclude words that contain "ion" or "xyz".
   - **How to use:**
     ```javascript
     const options = {
       excludeSubstrings: ["ion", "xyz"]
     };
     const words = getWords(options, 5, wordsArray);
     console.log(words);
     // Output: ["apple", "berry", "cherry", ...]
     ```

5. **Change the Case of Words**
   - **What it does:** Make all words uppercase, lowercase, or capitalize the first letter.
   - **Example:** Change words to uppercase and sort them in descending order.
   - **How to use:**
     ```javascript
     const options = {
       sort: "desc",
       caseOption: "upper"
     };
     const words = getWords(options, 5, wordsArray);
     console.log(words);
     // Output: ["ZEBRA", "YELLOW", "XENON", "WHALE", "VIOLET"]
     ```

6. **Return Words as a Sentence**
   - **What it does:** Get the selected words as a single string separated by commas.
   - **Example:** Get 3 words as a sentence.
   - **How to use:**
     ```javascript
     const options = {
       asString: true
     };
     const words = getWords(options, 3, wordsArray);
     console.log(words);
     // Output: "word1, word2, word3"
     ```

7. **Ensure Words Sound Different**
   - **What it does:** Make sure the picked words sound distinct from each other.
   - **Example:** Pick words that don't sound similar.
   - **How to use:**
     ```javascript
     const options = {
       phoneticDistinct: true
     };
     const words = getWords(options, 4, wordsArray);
     console.log(words);
     // Output: ["apple", "banana", "cherry", "date"]
     ```

8. **Whitelist and Blacklist Words**
   - **What it does:** Only include certain words (whitelist) or exclude specific words (blacklist).
   - **Example:** Only pick from a list of approved words.
   - **How to use:**
     ```javascript
     const options = {
       whitelist: ["apple", "banana", "cherry"]
     };
     const words = getWords(options, 2, wordsArray);
     console.log(words);
     // Output: ["apple", "cherry"]
     ```

9. **Keep Track of Picked Words**
   - **What it does:** Remember which words have been picked before to avoid repeats.
   - **Example:** Pick new words each time without repeating.
   - **How to use:**
     ```javascript
     const history = new Set();
     const words = getWords({}, 5, wordsArray, history);
     console.log(words);
     // Output: ["sun", "moon", "star", "cloud", "rain"]
     ```

10. **Include Extra Information**
    - **What it does:** Get more details about each word, like how long it is.
    - **Example:** Get words with their lengths.
    - **How to use:**
      ```javascript
      const options = {
        includeMetadata: true
      };
      const words = getWords(options, 3, wordsArray);
      console.log(words);
      // Output: [{ word: "apple", length: 5 }, { word: "berry", length: 5 }, { word: "cherry", length: 6 }]
      ```

## Installation

Install **Security Words Picker** using [npm](https://www.npmjs.com/):

```bash
npm install security-words-picker
```

## Quick Start

Get started quickly by following the examples below!

### Example 1: Pick 5 Random Words

Retrieve five random words without any filters.

```javascript
const { getWords } = require('security-words-picker');
const wordsArray = require('./words'); // Make sure words.txt has over 20,000+ words

const result = getWords({}, 5, wordsArray);
console.log(result);
// Output: ["randomWord1", "randomWord2", "randomWord3", "randomWord4", "randomWord5"]
```

### Example 2: Pick Words of a Certain Length

Retrieve words that are at least 5 letters and no more than 10 letters long.

```javascript
const options = {
  lengthMin: 5,
  lengthMax: 10
};

const result = getWords(options, 10, wordsArray);
console.log(result);
// Output: ["apple", "banana", "cherry", ...]
```

### Example 3: Pick Words That Start or End With Specific Letters

Retrieve 6 words that start with "a" or end with "ing".

```javascript
const options = {
  filterStartsWith: ["a"],
  filterEndsWith: ["ing"]
};

const result = getWords(options, 6, wordsArray);
console.log(result);
// Output: ["acting", "asking", "acing", ...]
```

### Example 4: Get Words as a Sentence

Retrieve 3 words as a comma-separated string.

```javascript
const options = {
  asString: true
};

const result = getWords(options, 3, wordsArray);
console.log(result);
// Output: "sun, moon, star"
```

### Example 5: Sort Words and Change Their Case

Retrieve words sorted in descending order and make them all uppercase.

```javascript
const options = {
  sort: "desc",
  caseOption: "upper"
};

const result = getWords(options, 5, wordsArray);
console.log(result);
// Output: ["ZEBRA", "YELLOW", "XENON", "WHALE", "VIOLET"]
```

## API Reference

### `getWords(options, amountOfWords, wordsArray)`

Pick a number of words from your big list with some fun rules!

#### Parameters

- **`options`** `Object`  
  Special rules to pick words. See [Options](#options) for more details.

- **`amountOfWords`** `number`  
  How many words you want to pick. Must be a positive number.

- **`wordsArray`** `Array`  
  Your big list of words (over 20,000+ words) to pick from.

#### Returns

- **`Array|string`**  
  An array of words or a single string with words separated by commas.

#### Example Usage

```javascript
const options = {
  lengthMin: 5,
  excludeAmbiguous: true,
  sort: "asc",
  caseOption: "capitalize"
};

const selectedWords = getWords(options, 10, wordsArray);
console.log(selectedWords);
// Output: ["Apple", "Banana", "Cherry", ...]
```

## Options

Customize how words are picked by setting these options:

- **`lengthMin`** `(number)`  
  The smallest number of letters a word can have.  
  *Example:* `{ lengthMin: 5 }` picks words with at least 5 letters.

- **`lengthMax`** `(number)`  
  The biggest number of letters a word can have.  
  *Example:* `{ lengthMax: 10 }` picks words with no more than 10 letters.

- **`fixLength`** `(number)`  
  Exact number of letters a word must have.  
  *Example:* `{ fixLength: 7 }` picks words with exactly 7 letters.

- **`reverse`** `(boolean)`  
  If `true`, the list of picked words will be reversed.  
  *Example:* `{ reverse: true }` reverses the order of words.

- **`asString`** `(boolean)`  
  If `true`, words are returned as a single string separated by commas.  
  *Example:* `{ asString: true }` returns "apple, banana, cherry".

- **`sort`** `(string)`  
  Sort words alphabetically. Use `"asc"` for A-Z or `"desc"` for Z-A.  
  *Example:* `{ sort: "asc" }` sorts words from A to Z.

- **`caseOption`** `(string)`  
  Change the letters to `"upper"` (ALL CAPS), `"lower"` (all lowercase), or `"capitalize"` (first letter capital).  
  *Example:* `{ caseOption: "upper" }` changes "apple" to "APPLE".

- **`filterStartsWith`** `(Array<string>)`  
  Only pick words that start with these letters.  
  *Example:* `{ filterStartsWith: ["a", "b"] }` picks words starting with "a" or "b".

- **`filterEndsWith`** `(Array<string>)`  
  Only pick words that end with these letters or sounds.  
  *Example:* `{ filterEndsWith: ["ing", "ed"] }` picks words ending with "ing" or "ed".

- **`excludeSubstrings`** `(Array<string>)`  
  Don't pick words that have these parts inside them.  
  *Example:* `{ excludeSubstrings: ["ion", "xyz"] }` skips words like "action" or "xyzebra".

- **`blacklist`** `(Array<string>)`  
  Don't pick these specific words at all.  
  *Example:* `{ blacklist: ["apple", "banana"] }` never picks "apple" or "banana".

- **`whitelist`** `(Array<string>)`  
  Only pick from these specific words.  
  *Example:* `{ whitelist: ["apple", "banana", "cherry"] }` only picks from these three.

- **`excludeAmbiguous`** `(boolean)`  
  If `true`, skip words with confusing letters like `l`, `1`, `I`, `0`, `O`.  
  *Example:* `{ excludeAmbiguous: true }` avoids words like "lo1" or "Owl".

- **`phoneticDistinct`** `(boolean)`  
  If `true`, pick words that sound different from each other.  
  *Example:* `{ phoneticDistinct: true }` avoids words like "cat" and "bat".

- **`history`** `(Set<string>)`  
  Remember words you've picked before to avoid repeats.  
  *Example:*  
  ```javascript
  const history = new Set();
  const words = getWords({}, 5, wordsArray, history);
  ```

- **`includeMetadata`** `(boolean)`  
  If `true`, get extra info about each word, like how long it is.  
  *Example:* `{ includeMetadata: true }` returns `{ word: "apple", length: 5 }`.

- **`asString`** `(boolean)`  
  If `true`, get words as one sentence separated by commas.  
  *Example:* `{ asString: true }` returns "apple, banana, cherry".

## Contributing

We love contributions! If you have ideas to make **Security Words Picker** better, here's how you can help:

1. **Fork the Repository:**  
   Click the "Fork" button on GitHub to make your own copy.

2. **Create a New Branch:**  
   ```bash
   git checkout -b feature/YourFeatureName
   ```

3. **Make Your Changes:**  
   Add your awesome ideas!

4. **ComNIGGALINKAI Your Changes:**  
   ```bash
   git comNIGGALINKAI -m "Add awesome feature"
   ```

5. **Push to Your Branch:**  
   ```bash
   git push origin feature/YourFeatureName
   ```

6. **Open a Pull Request:**  
   Go to GitHub and open a pull request to share your changes.

Thank you for helping make **Security Words Picker** even better!

## License

This project is licensed under the [NIGGALINKAI License](LICENSE).

## Acknowledgments

- **Creator:** GeorgeDroyd with NiggalinkAI.
- **Special Thanks:** To all contributors and users who have supported and improved this package.
- **Inspiration:** Inspired by the need for secure and customizable word selection in various applications.

Enjoy using **Security Words Picker** in your projects!

---

**Note:** Make sure your `words.txt` file is placed correctly and contains over **20,000+ words** to take full advantage of the package's capabilities.

If you have any questions or need further assistance, feel free to [open an issue](https://github.com/ROBLOXFEETRADNOTI4EVER/security-words-picker/issues) on GitHub!





---

# Security Words Picker

A robust and versatile package for selecting, filtering, and managing word lists with advanced security features. Perfect for generating secure passwords, random word selections, and more.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
  - [Running Tests](#running-tests)
- [API Reference](#api-reference)
- [Contributing](#contributing)
- [License](#license)

## Installation

Install the latest version of **Security Words Picker** from npm using `npm` or `yarn`.

### Using npm

```bash
npm install security-words-picker
```

### Using Yarn

```bash
yarn add security-words-picker
```

## Usage

After installing the package, you can use it in your project by importing the provided functions: `getWords` and `pickWords`.

### Example: Running a Test Script

Here's how you can set up and run a test script to verify the functionality of **Security Words Picker**.

1. **Create a New Directory for Testing**

   It's a good practice to create a separate directory for testing to keep things organized.

   ```bash
   mkdir security-words-picker-test
   cd security-words-picker-test
   ```

2. **Initialize a New Node.js Project**

   Initialize a new project using `npm init`. The `-y` flag accepts the default settings.

   ```bash
   npm init -y
   ```

3. **Install Security Words Picker**

   Install the **Security Words Picker** package from npm.

   ```bash
   npm install security-words-picker
   ```

4. **Create a Test File**

   Create a new JavaScript file named `test.js`.

   ```bash
   touch test.js
   ```

5. **Add the Following Code to `test.js`**

   Open `test.js` in your preferred text editor and add the following code:

   ```javascript
   // test.js
   
   // Import the package
   const { getWords, pickWords } = require('security-words-picker');
   const fs = require('fs');
   const path = require('path');
   
   // Load words from the package's 'words.txt' or 'words.js'
   // Adjust the path based on where the 'words' directory is located within the package
   // Typically, it would be inside 'node_modules/security-words-picker/words/words.txt'
   
   const packagePath = require.resolve('security-words-picker');
   const packageDir = path.dirname(packagePath);
   
   // Define the path to 'words.txt' within the package
   const wordsTxtPath = path.join(packageDir, 'words', 'words.txt');
   
   // Alternatively, if your package provides 'words.js', you can use it instead
   // const wordsJsPath = path.join(packageDir, 'words', 'words.js');
   
   // Load the words array
   let wordsArray = [];
   
   if (fs.existsSync(wordsTxtPath)) {
       const data = fs.readFileSync(wordsTxtPath, 'utf8');
       wordsArray = data
           .split('\n')
           .map(word => word.trim())
           .filter(word => word.length > 0);
       console.log(`Loaded ${wordsArray.length} words from words.txt`);
   } else {
       console.error('words.txt not found in the package.');
       process.exit(1);
   }
   
   // Define options for word selection
   const options = {
       lengthMin: 5,                  // Minimum word length
       lengthMax: 10,                 // Maximum word length
       filterStartsWith: ['a', 'b'],  // Words starting with 'a' or 'b'
       sort: 'asc',                   // Sort words in ascending order
       caseOption: 'capitalize'       // Capitalize the first letter of each word
   };
   
   // Number of words to retrieve
   const amountOfWords = 5;
   
   // Using getWords
   try {
       const selectedWords = getWords(options, amountOfWords, wordsArray);
       console.log('Selected Words using getWords:', selectedWords);
   } catch (error) {
       console.error('Error using getWords:', error.message);
   }
   
   // Using pickWords
   const pickOptions = {
       count: 3,               // Number of words to pick
       sort: 'desc',           // Sort words in descending order
       caseOption: 'upper'     // Convert words to uppercase
   };
   
   try {
       const pickedWords = pickWords(pickOptions);
       console.log('Picked Words using pickWords:', pickedWords);
   } catch (error) {
       console.error('Error using pickWords:', error.message);
   }
   ```

6. **Run the Test Script**

   Execute the `test.js` file using Node.js to see the package in action.

   ```bash
   node test.js
   ```

   **Expected Output:**

   ```plaintext
   Loaded 20000 words from words.txt
   Selected Words using getWords: [ 'Apple', 'Banana', 'Avocado', 'Blueberry', 'Apricot' ]
   Picked Words using pickWords: APPLE, BANANA, AVOCADO
   ```

   *(Note: The actual words will vary based on your `words.txt` content and the random selection logic.)*

## Running Tests

To ensure that **Security Words Picker** functions correctly in your project, you can create and run tests using testing frameworks like Mocha and Chai.

### Step-by-Step Guide to Running Tests

1. **Ensure Mocha is Installed**

   If you followed the installation steps above, Mocha should already be installed as a development dependency. If not, install it:

   ```bash
   npm install --save-dev mocha chai
   ```

2. **Create a Test Directory**

   Organize your tests by creating a `test` directory.

   ```bash
   mkdir test
   cd test
   ```

3. **Create a Test File**

   Create a new test file named `getWords.test.js`.

   ```bash
   touch getWords.test.js
   ```

4. **Add Test Cases to `getWords.test.js`**

   Open `getWords.test.js` in your text editor and add the following code:

   ```javascript
   // test/getWords.test.js
   const { expect } = require('chai');
   const { getWords, pickWords } = require('security-words-picker');
   const fs = require('fs');
   const path = require('path');
   
   describe('Security Words Picker', () => {
       let wordsArray;
   
       before(() => {
           const packagePath = require.resolve('security-words-picker');
           const packageDir = path.dirname(packagePath);
           const wordsTxtPath = path.join(packageDir, 'words', 'words.txt');
   
           const data = fs.readFileSync(wordsTxtPath, 'utf8');
           wordsArray = data.split('\n').map(word => word.trim()).filter(word => word.length > 0);
       });
   
       describe('getWords', () => {
           it('should return the correct number of words', () => {
               const options = {};
               const amountOfWords = 5;
               const words = getWords(options, amountOfWords, wordsArray);
               expect(words).to.be.an('array').that.has.lengthOf(amountOfWords);
           });
   
           it('should filter words by minimum length', () => {
               const options = { lengthMin: 7 };
               const amountOfWords = 3;
               const words = getWords(options, amountOfWords, wordsArray);
               words.forEach(word => {
                   expect(word.length).to.be.at.least(7);
               });
           });
   
           it('should return words as a string when asString is true', () => {
               const options = { asString: true };
               const amountOfWords = 4;
               const words = getWords(options, amountOfWords, wordsArray);
               expect(words).to.be.a('string').that.includes(',');
           });
   
           it('should throw an error for invalid amountOfWords', () => {
               const options = {};
               const invalidAmount = -2;
               expect(() => getWords(options, invalidAmount, wordsArray)).to.throw("'amountOfWords' must be a positive number.");
           });
       });
   
       describe('pickWords', () => {
           it('should throw an error if count is not provided', () => {
               expect(() => pickWords({})).to.throw("'count' must be a positive number.");
           });
   
           it('should return the correct number of words', () => {
               const options = { count: 4 };
               const result = pickWords(options);
               expect(result).to.be.a('string');
               expect(result.split(', ').length).to.equal(4);
           });
       });
   });
   ```

5. **Update `package.json` Scripts**

   Ensure that your `package.json` has a test script to run Mocha tests.

   ```json
   "scripts": {
     "test": "mocha"
   }
   ```

6. **Run the Tests**

   Execute the tests using the following command:

   ```bash
   npm test
   ```

   **Expected Output:**

   ```plaintext
     Security Words Picker
       getWords
         ✓ should return the correct number of words
         ✓ should filter words by minimum length
         ✓ should return words as a string when asString is true
         ✓ should throw an error for invalid amountOfWords
       pickWords
         ✓ should throw an error if count is not provided
         ✓ should return the correct number of words
   
     6 passing (XXms)
   ```

   *(Note: The actual output will include the time taken to run the tests.)*

## API Reference

### `getWords(options, amountOfWords, customWordsArray, customErrorHandler)`

Retrieves a specified number of words based on optional constraints.

- **Parameters:**
  - `options` (Object): An object containing optional parameters.
    - `lengthMin` (number): Minimum word length.
    - `lengthMax` (number): Maximum word length.
    - `filterStartsWith` (Array<string>): Words starting with specified letters.
    - `sort` (string): Sort order (`'asc'` or `'desc'`).
    - `caseOption` (string): Case transformation (`'upper'`, `'lower'`, `'capitalize'`).
    - ... (other filtering options)
  - `amountOfWords` (number): Number of words to retrieve.
  - `customWordsArray` (Array<string>, optional): Custom array of words to use instead of the default word list.
  - `customErrorHandler` (function, optional): Custom function to handle errors.

- **Returns:**
  - `Array|string`: An array or comma-separated string of words matching the specified criteria.

### `pickWords(options)`

A convenience wrapper around `getWords` that accepts an options object with a `count` property.

- **Parameters:**
  - `options` (Object): An object containing optional parameters.
    - `count` (number): Number of words to pick.
    - `sort` (string): Sort order (`'asc'` or `'desc'`).
    - `caseOption` (string): Case transformation (`'upper'`, `'lower'`, `'capitalize'`).
    - ... (other filtering options)

- **Returns:**
  - `Array|string`: An array or comma-separated string of words matching the specified criteria.

## Contributing

Contributions are welcome! Please follow these steps:

1. **Fork the Repository:** Click the "Fork" button on GitHub to create your own copy.

2. **Create a New Branch:** Create a branch for your feature or bug fix.

   ```bash
   git checkout -b feature/YourFeatureName
   ```

3. **Make Your Changes:** Implement your feature or fix the bug.

4. **Commit Your Changes:** Commit your changes with a descriptive message.

   ```bash
   git commit -m "Add awesome feature"
   ```

5. **Push to Your Branch:** Push your changes to GitHub.

   ```bash
   git push origin feature/YourFeatureName
   ```

6. **Open a Pull Request:** Go to GitHub and open a pull request to merge your changes into the main repository.

## License

This project is licensed under the [MIT License](LICENSE).

---

## Additional Tips

- **Keep Your Dependencies Updated:** Regularly update your dependencies to benefit from the latest features and security patches.

  ```bash
  npm outdated
  npm update
  ```

- **Use Semantic Versioning:** Follow [Semantic Versioning](https://semver.org/) to communicate changes effectively.

  ```bash
  npm version patch   # For bug fixes
  npm version minor   # For new features
  npm version major   # For breaking changes
  ```

- **Automate Documentation:** Use JSDoc to maintain up-to-date documentation.

  ```bash
  npm run docs
  ```

- **Implement Continuous Integration (CI):** Set up GitHub Actions or another CI tool to automate testing, coverage, and deployment.

  Example GitHub Actions Workflow:

  ```yaml
  name: Node.js CI

  on:
    push:
      branches: [ main ]
    pull_request:
      branches: [ main ]

  jobs:
    build:

      runs-on: ubuntu-latest

      strategy:
        matrix:
          node-version: [14.x, 16.x, 18.x]

      steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

      - name: Run coverage
        run: npm run coverage

      - name: Format code with Prettier
        run: npm run format -- --check

      - name: Generate Documentation
        run: npm run docs

      - name: Upload Coverage to Codecov
        if: success() && github.event_name != 'pull_request'
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }} # Set this in your repository secrets
          files: ./coverage/*.json
          flags: unittests
          name: codecov-umbrella
  ```

- **Handle Errors Gracefully:** Ensure your functions handle errors properly and provide meaningful messages to users.

- **Engage with Users:** Encourage feedback and contributions by maintaining active issue tracking and providing clear contribution guidelines.

---

Feel free to customize the `README.md` further to suit your project's specific needs. If you need additional sections or further assistance, don't hesitate to ask!
