Skip to content

Commit 318fb6e

Browse files
authored
feat(new-tool): add email normalizer (CorentinTh#1243)
1 parent f1a5489 commit 318fb6e

File tree

6 files changed

+101
-0
lines changed

6 files changed

+101
-0
lines changed

components.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ declare module '@vue/runtime-core' {
7272
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
7373
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
7474
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
75+
EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
7576
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
7677
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
7778
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
@@ -132,13 +133,18 @@ declare module '@vue/runtime-core' {
132133
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
133134
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
134135
NEllipsis: typeof import('naive-ui')['NEllipsis']
136+
NForm: typeof import('naive-ui')['NForm']
137+
NFormItem: typeof import('naive-ui')['NFormItem']
135138
NH1: typeof import('naive-ui')['NH1']
136139
NH3: typeof import('naive-ui')['NH3']
137140
NIcon: typeof import('naive-ui')['NIcon']
141+
NInputNumber: typeof import('naive-ui')['NInputNumber']
138142
NLayout: typeof import('naive-ui')['NLayout']
139143
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
140144
NMenu: typeof import('naive-ui')['NMenu']
141145
NScrollbar: typeof import('naive-ui')['NScrollbar']
146+
NSlider: typeof import('naive-ui')['NSlider']
147+
NSwitch: typeof import('naive-ui')['NSwitch']
142148
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
143149
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
144150
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"crypto-js": "^4.1.1",
5858
"date-fns": "^2.29.3",
5959
"dompurify": "^3.0.6",
60+
"email-normalizer": "^1.0.0",
6061
"emojilib": "^3.0.10",
6162
"figlet": "^1.7.0",
6263
"figue": "^1.2.0",

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<script setup lang="ts">
2+
import { normalizeEmail } from 'email-normalizer';
3+
import { withDefaultOnError } from '@/utils/defaults';
4+
import { useCopy } from '@/composable/copy';
5+
6+
const emails = ref('');
7+
const normalizedEmails = computed(() => {
8+
if (!emails.value) {
9+
return '';
10+
}
11+
12+
return emails.value
13+
.split('\n')
14+
.map((email) => {
15+
return withDefaultOnError(() => normalizeEmail({ email }), `Unable to parse email: ${email}`);
16+
})
17+
.join('\n');
18+
});
19+
20+
const { copy } = useCopy({ source: normalizedEmails, text: 'Normalized emails copied to the clipboard', createToast: true });
21+
</script>
22+
23+
<template>
24+
<div>
25+
<div class="mb-2">
26+
Raw emails to normalize:
27+
</div>
28+
<c-input-text
29+
v-model:value="emails"
30+
placeholder="Put your emails here (one per line)..."
31+
rows="3"
32+
multiline
33+
autocomplete="off"
34+
autocorrect="off"
35+
autocapitalize="off"
36+
spellcheck="false"
37+
autofocus
38+
monospace
39+
/>
40+
41+
<div class="mb-2 mt-4">
42+
Normalized emails:
43+
</div>
44+
<c-input-text
45+
:value="normalizedEmails"
46+
placeholder="Normalized emails will appear here..."
47+
rows="3"
48+
autocomplete="off"
49+
autocorrect="off"
50+
autocapitalize="off"
51+
spellcheck="false"
52+
multiline
53+
readonly
54+
monospace
55+
/>
56+
<div class="mt-4 flex justify-center gap-2">
57+
<c-button @click="emails = ''">
58+
Clear emails
59+
</c-button>
60+
<c-button :disabled="!normalizedEmails" @click="copy()">
61+
Copy normalized emails
62+
</c-button>
63+
</div>
64+
</div>
65+
</template>

src/tools/email-normalizer/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Mail } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'Email normalizer',
6+
path: '/email-normalizer',
7+
description: 'Normalize email addresses to a standard format for easier comparison. Useful for deduplication and data cleaning.',
8+
keywords: ['email', 'normalizer'],
9+
component: () => import('./email-normalizer.vue'),
10+
icon: Mail,
11+
createdAt: new Date('2024-08-15'),
12+
});

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { tool as base64FileConverter } from './base64-file-converter';
22
import { tool as base64StringConverter } from './base64-string-converter';
33
import { tool as basicAuthGenerator } from './basic-auth-generator';
4+
import { tool as emailNormalizer } from './email-normalizer';
45

56
import { tool as asciiTextDrawer } from './ascii-text-drawer';
67

@@ -152,6 +153,7 @@ export const toolsByCategory: ToolCategory[] = [
152153
dockerRunToDockerComposeConverter,
153154
xmlFormatter,
154155
yamlViewer,
156+
emailNormalizer,
155157
],
156158
},
157159
{

0 commit comments

Comments
 (0)