From 7ce1232707e1260c02cd6a896ab94f2cfcfdd520 Mon Sep 17 00:00:00 2001 From: Fityan Date: Sun, 12 Nov 2023 14:12:50 +0700 Subject: [PATCH 1/3] fix: remove `dirname` from vitest config alias --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index 6a1c05d..bd0921e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ test: { root: './', alias: { - '~': path.resolve(__dirname, './src'), + '~': path.resolve('./src'), }, coverage: { provider: 'v8', From 95cd98338e3c6c0367d40bfd3334ca4dec77eef2 Mon Sep 17 00:00:00 2001 From: Fityan Date: Sun, 12 Nov 2023 14:39:35 +0700 Subject: [PATCH 2/3] refactor: use JSON.parse and change to sync functions fix importing JSON with JSON.parse --- README.md | 12 +++++++----- src/index.ts | 18 ++++++++++++++---- test/benchmark.spec.ts | 4 ++-- test/index.spec.ts | 28 ++++++++++++++-------------- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 33f56f7..d15fd65 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,21 @@ import wisely from 'wisely'; const text = 'Palestine will be free! Freedom is the right of ALL nations!'; // 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! +const res1 = wisely({ text }); // Only obscures the specified phrases -await wisely({ text, phrases: ['palestine', 'free'] }); -// Output: P4l35t1n3 will be fr33! Freedom is the right of ALL nations! +const res2 = wisely({ text, phrases: ['palestine', 'free'] }); + +console.log(res1, res2); +// P@l3$t|n3 w!ll 83 fr33! Fr33d0m |$ t#3 r!6#t 0f @LL n4t|0n5! +// P4l35t1n3 will be fr33! Freedom is the right of ALL nations! ``` ## API ### wisely(options) -Returns a `Promise` that resolves to a `string` with the obsfucated text. +Returns a `string` with the obsfucated text. #### options diff --git a/src/index.ts b/src/index.ts index 5b5a45d..59eb8c0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,18 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + export type CharSetNames = 'latin' | 'latin-1'; export type CharSet = Record; -async function getCharSet(name: CharSetNames = 'latin'): Promise { - return import(`../charsets/${name}.json`) as Promise; +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +function getCharSet(name: CharSetNames = 'latin'): CharSet { + const strJson = fs.readFileSync( + path.resolve(dirname, `../charsets/${name}.json`), + { encoding: 'utf8' }, + ); + return JSON.parse(strJson) as CharSet; } function getChar(char: string, charSet: CharSet, caseSensitive?: boolean) { @@ -26,8 +36,8 @@ export type Options = { charSet?: CharSetNames; }; -export default async function wisely(options: Options): Promise { - const charSet = await getCharSet(options.charSet); +export default function wisely(options: Options): string { + const charSet = getCharSet(options.charSet); const censor = (phrase: string): string => phrase.split('') .map((char) => getChar(char, charSet, options.caseSensitive)) diff --git a/test/benchmark.spec.ts b/test/benchmark.spec.ts index 7d082e1..376adf0 100644 --- a/test/benchmark.spec.ts +++ b/test/benchmark.spec.ts @@ -3,11 +3,11 @@ import { performance } from 'perf_hooks'; import fs from 'node:fs'; import wisely from '~/index.js'; -test('perf on large string must <= 20ms', async () => { +test('large text', () => { const text = fs.readFileSync('test/large-string.txt', 'utf-8'); const startTime = performance.now(); - const res = await wisely({ text, phrases: ['pulau'] }); + const res = wisely({ text, phrases: ['pulau'] }); const diff = performance.now() - startTime; console.log(`Perf: ${diff}ms`); diff --git a/test/index.spec.ts b/test/index.spec.ts index 3938307..e8bf514 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -4,8 +4,8 @@ import wisely from '~/index.js'; describe('wisely', () => { const text = 'Palestine will be free! Freedom is the right of ALL nations!'; - test('valid', async () => { - const result = await wisely({ text }); + test('valid', () => { + const result = wisely({ text }); expect(result).not.equal(''); expect(result).not.equal(text); @@ -16,10 +16,10 @@ describe('wisely', () => { test.each([ { phrase: 'palestine', unaffected: 'will be' }, { phrase: 'free', unaffected: 'Freedom' }, - ])('with specific phrases provided: $phrase', async ({ + ])('with specific phrases provided: $phrase', ({ phrase, unaffected, }) => { - const result = await wisely({ text, phrases: [phrase] }); + const result = wisely({ text, phrases: [phrase] }); expect(result).contain(unaffected); expect(result).not.match(new RegExp(`\\b${phrase}\\b`, 'i')); @@ -29,8 +29,8 @@ describe('wisely', () => { test.each([ { testText: 'AABBCCDDz', contains: '48Dz', notContains: '@BC2' }, { testText: 'aabbccddZ', contains: '@6cd2', notContains: '48Dz' }, - ])('case sensitive: $testText', async ({ testText, contains, notContains }) => { - const result = await wisely({ text: testText, caseSensitive: true }); + ])('case sensitive: $testText', ({ testText, contains, notContains }) => { + const result = wisely({ text: testText, caseSensitive: true }); contains.split('').forEach((char) => { expect(result).contain(char); @@ -43,22 +43,22 @@ describe('wisely', () => { expect(result).toHaveLength(testText.length); }); - test('no phrases found in the text', async () => { - expect(await wisely({ text, phrases: ['foo'] })).toEqual(text); + test('no phrases found in the text', () => { + expect(wisely({ text, phrases: ['foo'] })).toEqual(text); }); - test('empty text', async () => { - expect(await wisely({ text: '' })).toEqual(''); + test('empty text', () => { + expect(wisely({ text: '' })).toEqual(''); }); - test('empty phrases', async () => { - expect(await wisely({ text, phrases: [] })).toEqual(text); + test('empty phrases', () => { + expect(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' }); + ])('with specific charSet (latin-1): $testText', ({ testText, contains, notContains }) => { + const result = wisely({ text: testText, charSet: 'latin-1' }); contains.split('').forEach((char) => { expect(result).contain(char); From 0bf3585dcabeb316923139aed87fc439c0c06065 Mon Sep 17 00:00:00 2001 From: Fityan Date: Sun, 12 Nov 2023 15:07:58 +0700 Subject: [PATCH 3/3] chore: update tsconfig: use "Next" target & module, remove resolve json --- tsconfig.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 8329e32..d4c53c8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,12 @@ { "compilerOptions": { - "target": "ES2022", - "lib": [ - "ES2022", - ], + "target": "ESNext", "declaration": true, "declarationMap": true, "sourceMap": true, "outDir": "lib", - "module": "Node16", - "moduleResolution": "Node16", - "esModuleInterop": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "baseUrl": "./", @@ -20,7 +16,6 @@ ], }, "strict": true, - "resolveJsonModule": true, }, "exclude": [ "node_modules",