Skip to content

Commit

Permalink
feat: add latin-1 charset
Browse files Browse the repository at this point in the history
  • Loading branch information
fityannugroho committed Nov 12, 2023
1 parent e2ea931 commit fbaf041
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 14 deletions.
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Current Test File",
"autoAttachChildProcesses": true,
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**"
],
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
"args": [
"run",
"${relativeFile}"
],
"smartStep": true,
"console": "integratedTerminal"
}
]
}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Fityandhiya Islam Nugroho <[email protected]>

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.
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Wisely

Replace sensitive phrases with special characters to avoid bans. Everyone is free to speak as long as they do so **wisely**.
Obfuscating text or phrases with random uncommon characters to avoid banning. Everyone is free to speak as long as they do so **wisely**.

## Prerequisites

Expand All @@ -20,11 +20,11 @@ import wisely from 'wisely';

const text = 'Palestine will be free! Freedom is the right of ALL nations!';

// Replace the whole text
// Obscuring the whole text
await wisely({ text });
// Output: P@l3$t|n3 w!ll 83 fr33! Fr33d0m |$ t#3 r!6#t 0f @LL n4t|0n5!

// Only replace the specified phrases
// Only obscures the specified phrases
await wisely({ text, phrases: ['palestine', 'free'] });
// Output: P4l35t1n3 will be fr33! Freedom is the right of ALL nations!
```
Expand All @@ -33,7 +33,7 @@ await wisely({ text, phrases: ['palestine', 'free'] });

### wisely(options)

Returns a `Promise` that resolves to a `string` with the replaced text.
Returns a `Promise` that resolves to a `string` with the obsfucated text.

#### options

Expand All @@ -44,34 +44,43 @@ Type: `object`
Type: `string`
Required: `true`

The text to be replaced.
The text to be obscured.

##### phrases

Type: `string[]` \
Required: `false`

The specific phrases to be replaced. If not specified, the whole text will be replaced.
The specific phrases to be obscured. If not specified, the whole text will be obscured.

##### caseSensitive

Type: `boolean` \
Default: `false`

Whether to replace the phrases in a case-sensitive manner.
Whether to obscure in a case-sensitive manner.

##### charSet

Type: `string` \
Default: `'latin'` \
Values: `'latin'`
Values: `'latin'` | `'latin-1'`

The character set to be used for replacing. Currently, only the [Basic Latin](https://unicodeplus.com/block/0000) is supported.
The character set that will be used for obfuscation.

> In the future, we will add support for more character sets to improve the variety of the replaced text. Also, we will add support to define custom character sets.
> In the future, we will add support for more character sets to improve the variety of the obsfucated text. Also, we will add support to define custom character sets.
## Support This Project

Give a ⭐️ if this project helped you!

Also please consider supporting this project by **becoming a sponsor**. Your donation will help us to maintain and develop this project and provide you with better support.

## Character Sets

Below is the built-in character sets available. See the details of each character set in the [charsets](./charsets) directory.

| `charSet` | Block Name | Block Range |
| ---- | --------- | ----- |
| `latin` | [Basic Latin](https://unicodeplus.com/block/0000) | \u0000 - \u007f |
| `latin-1` | [Latin-1 Supplement](https://unicodeplus.com/block/0080) | \u0080 - \u00ff |
25 changes: 25 additions & 0 deletions charsets/latin-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"A": ["\u00c0", "\u00c1", "\u00c2", "\u00c3", "\u00c4", "\u00c5"],
"a": ["\u00e0", "\u00e1", "\u00e2", "\u00e3", "\u00e4", "\u00e5", "\u00aa"],
"B": ["\u00df"],
"C": ["\u00a2", "\u00a9", "\u00c7"],
"c": ["\u00e7"],
"D": ["\u00d0"],
"E": ["\u00a3", "\u00c8", "\u00c9", "\u00ca", "\u00cb"],
"e": ["\u00e8", "\u00e9", "\u00ea", "\u00eb"],
"I": ["\u00cc", "\u00cd", "\u00ce", "\u00cf"],
"i": ["\u00a1", "\u00ec", "\u00ed", "\u00ee", "\u00ef"],
"N": ["\u00d1"],
"n": ["\u00f1"],
"O": ["\u00d2", "\u00d3", "\u00d4", "\u00d5", "\u00d6", "\u00d8"],
"o": ["\u00ba", "\u00f2", "\u00f3", "\u00f4", "\u00f5", "\u00f6", "\u00f8"],
"P": ["\u00b6"],
"p": ["\u00de"],
"R": ["\u00ae"],
"S": ["\u00a7"],
"U": ["\u00d9", "\u00da", "\u00db", "\u00dc"],
"u": ["\u00f9", "\u00fa", "\u00fb", "\u00fc"],
"x": ["\u00d7"],
"Y": ["\u00a5", "\u00dd"],
"y": ["\u00fd", "\u00ff"]
}
File renamed without changes.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"name": "wisely",
"version": "0.1.0",
"description": "Replace sensitive phrases with special characters to avoid bans.",
"description": "Obfuscating text or phrases with random uncommon characters to avoid banning.",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"charsets/",
"dist/"
],
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
Expand All @@ -21,8 +25,11 @@
"keywords": [
"ban",
"filter",
"random",
"regex",
"obsfucation",
"obfuscate",
"obscure",
"string",
"text",
"unicode",
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export type CharSetNames = 'latin';
export type CharSetNames = 'latin' | 'latin-1';
export type CharSet = Record<string, string[] | undefined>;

async function getCharSet(name: CharSetNames = 'latin'): Promise<CharSet> {
return import(`./charsets/${name}.json`) as Promise<CharSet>;
return import(`../charsets/${name}.json`) as Promise<CharSet>;
}

function getChar(char: string, charSet: CharSet, caseSensitive?: boolean) {
Expand Down Expand Up @@ -33,7 +33,7 @@ export default async function wisely(options: Options): Promise<string> {
.map((char) => getChar(char, charSet, options.caseSensitive))
.join('');

if (!options.phrases?.length) {
if (!options.phrases) {
return censor(options.text);
}

Expand Down
28 changes: 28 additions & 0 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('wisely', () => {
expect(result).not.equal('');
expect(result).not.equal(text);
expect(result).not.contain('will be');
expect(result).toHaveLength(text.length);
});

test.each([
Expand All @@ -22,6 +23,7 @@ describe('wisely', () => {

expect(result).contain(unaffected);
expect(result).not.match(new RegExp(`\\b${phrase}\\b`, 'i'));
expect(result).toHaveLength(text.length);
});

test.each([
Expand All @@ -37,9 +39,35 @@ describe('wisely', () => {
notContains.split('').forEach((char) => {
expect(result).not.contain(char);
});

expect(result).toHaveLength(testText.length);
});

test('no phrases found in the text', async () => {
expect(await wisely({ text, phrases: ['foo'] })).toEqual(text);
});

test('empty text', async () => {
expect(await wisely({ text: '' })).toEqual('');
});

test('empty phrases', async () => {
expect(await wisely({ text, phrases: [] })).toEqual(text);
});

test.each([
{ testText: 'AaBbCcDdXxZz', contains: '\u00df\u00d7Zz', notContains: 'AaBbCcDdXx' },
])('with specific charSet (latin-1): $testText', async ({ testText, contains, notContains }) => {
const result = await wisely({ text: testText, charSet: 'latin-1' });

contains.split('').forEach((char) => {
expect(result).contain(char);
});

notContains.split('').forEach((char) => {
expect(result).not.contain(char);
});

expect(result).toHaveLength(testText.length);
});
});

0 comments on commit fbaf041

Please sign in to comment.