Skip to content

Commit 382a5cc

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/mongo-objectid
2 parents f7b024a + 318fb6e commit 382a5cc

File tree

10 files changed

+216
-17
lines changed

10 files changed

+216
-17
lines changed

components.d.ts

Lines changed: 6 additions & 4 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']
@@ -110,6 +111,7 @@ declare module '@vue/runtime-core' {
110111
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
111112
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
112113
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
114+
JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default']
113115
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
114116
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
115117
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
@@ -134,19 +136,18 @@ declare module '@vue/runtime-core' {
134136
NDatePicker: typeof import('naive-ui')['NDatePicker']
135137
NDivider: typeof import('naive-ui')['NDivider']
136138
NEllipsis: typeof import('naive-ui')['NEllipsis']
139+
NForm: typeof import('naive-ui')['NForm']
137140
NFormItem: typeof import('naive-ui')['NFormItem']
138-
NGi: typeof import('naive-ui')['NGi']
139-
NGrid: typeof import('naive-ui')['NGrid']
140141
NH1: typeof import('naive-ui')['NH1']
141142
NH3: typeof import('naive-ui')['NH3']
142143
NIcon: typeof import('naive-ui')['NIcon']
143144
NInputNumber: typeof import('naive-ui')['NInputNumber']
144-
NLabel: typeof import('naive-ui')['NLabel']
145145
NLayout: typeof import('naive-ui')['NLayout']
146146
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
147147
NMenu: typeof import('naive-ui')['NMenu']
148148
NScrollbar: typeof import('naive-ui')['NScrollbar']
149-
NSpin: typeof import('naive-ui')['NSpin']
149+
NSlider: typeof import('naive-ui')['NSlider']
150+
NSwitch: typeof import('naive-ui')['NSwitch']
150151
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
151152
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
152153
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -188,6 +189,7 @@ declare module '@vue/runtime-core' {
188189
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
189190
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
190191
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
192+
XmlToJson: typeof import('./src/tools/xml-to-json/xml-to-json.vue')['default']
191193
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
192194
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
193195
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']

package.json

Lines changed: 2 additions & 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",
@@ -92,6 +93,7 @@
9293
"vue-router": "^4.1.6",
9394
"vue-tsc": "^1.8.1",
9495
"xml-formatter": "^3.3.2",
96+
"xml-js": "^1.6.11",
9597
"yaml": "^2.2.1"
9698
},
9799
"devDependencies": {

pnpm-lock.yaml

Lines changed: 37 additions & 13 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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
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

78
import { tool as textToUnicode } from './text-to-unicode';
89
import { tool as safelinkDecoder } from './safelink-decoder';
910
import { tool as mongoObjectidConverter } from './mongo-objectid-converter';
11+
import { tool as xmlToJson } from './xml-to-json';
12+
import { tool as jsonToXml } from './json-to-xml';
1013
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
1114
import { tool as numeronymGenerator } from './numeronym-generator';
1215
import { tool as macAddressGenerator } from './mac-address-generator';
@@ -108,6 +111,8 @@ export const toolsByCategory: ToolCategory[] = [
108111
listConverter,
109112
tomlToJson,
110113
tomlToYaml,
114+
xmlToJson,
115+
jsonToXml,
111116
],
112117
},
113118
{
@@ -149,6 +154,7 @@ export const toolsByCategory: ToolCategory[] = [
149154
dockerRunToDockerComposeConverter,
150155
xmlFormatter,
151156
yamlViewer,
157+
emailNormalizer,
152158
mongoObjectidConverter,
153159
],
154160
},

src/tools/json-to-xml/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Braces } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'JSON to XML',
6+
path: '/json-to-xml',
7+
description: 'Convert JSON to XML',
8+
keywords: ['json', 'xml'],
9+
component: () => import('./json-to-xml.vue'),
10+
icon: Braces,
11+
createdAt: new Date('2024-08-09'),
12+
});

src/tools/json-to-xml/json-to-xml.vue

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script setup lang="ts">
2+
import convert from 'xml-js';
3+
import JSON5 from 'json5';
4+
import { withDefaultOnError } from '@/utils/defaults';
5+
import type { UseValidationRule } from '@/composable/validation';
6+
7+
const defaultValue = '{"a":{"_attributes":{"x":"1.234","y":"It\'s"}}}';
8+
function transformer(value: string) {
9+
return withDefaultOnError(() => {
10+
return convert.js2xml(JSON5.parse(value), { compact: true });
11+
}, '');
12+
}
13+
14+
const rules: UseValidationRule<string>[] = [
15+
{
16+
validator: (v: string) => v === '' || JSON5.parse(v),
17+
message: 'Provided JSON is not valid.',
18+
},
19+
];
20+
</script>
21+
22+
<template>
23+
<format-transformer
24+
input-label="Your JSON content"
25+
:input-default="defaultValue"
26+
input-placeholder="Paste your JSON content here..."
27+
output-label="Converted XML"
28+
output-language="xml"
29+
:transformer="transformer"
30+
:input-validation-rules="rules"
31+
/>
32+
</template>

src/tools/xml-to-json/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Braces } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'XML to JSON',
6+
path: '/xml-to-json',
7+
description: 'Convert XML to JSON',
8+
keywords: ['xml', 'json'],
9+
component: () => import('./xml-to-json.vue'),
10+
icon: Braces,
11+
createdAt: new Date('2024-08-09'),
12+
});

0 commit comments

Comments
 (0)