aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/index.ts3
-rw-r--r--src/tools/url-parser/index.ts11
-rw-r--r--src/tools/url-parser/url-parser.vue118
3 files changed, 131 insertions, 1 deletions
diff --git a/src/tools/index.ts b/src/tools/index.ts
index e4de3af..f46f784 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,7 @@
import { LockOpen } from '@vicons/tabler';
import type { ToolCategory } from './Tool';
+import { tool as urlParser } from './url-parser';
import { tool as deviceInformation } from './device-information';
import { tool as bcrypt } from './bcrypt';
import { tool as caseConverter } from './case-converter';
@@ -36,7 +37,7 @@ export const toolsByCategory: ToolCategory[] = [
{
name: 'Web',
icon: LockOpen,
- components: [urlEncoder, qrCodeGenerator, deviceInformation],
+ components: [urlEncoder, qrCodeGenerator, urlParser, deviceInformation],
},
{
name: 'Development',
diff --git a/src/tools/url-parser/index.ts b/src/tools/url-parser/index.ts
new file mode 100644
index 0000000..b46de14
--- /dev/null
+++ b/src/tools/url-parser/index.ts
@@ -0,0 +1,11 @@
+import { Unlink } from '@vicons/tabler';
+import type { ITool } from './../Tool';
+
+export const tool: ITool = {
+ name: 'Url parser',
+ path: '/url-parser',
+ description: 'Parse an url string to get all the differents parts (protocol, origin, params, port, username-password, ...)',
+ keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'],
+ component: () => import('./url-parser.vue'),
+ icon: Unlink,
+};
diff --git a/src/tools/url-parser/url-parser.vue b/src/tools/url-parser/url-parser.vue
new file mode 100644
index 0000000..d35923b
--- /dev/null
+++ b/src/tools/url-parser/url-parser.vue
@@ -0,0 +1,118 @@
+<template>
+ <n-card>
+ <n-form-item
+ label="Your url to parse:"
+ :feedback="validation.message"
+ :validation-status="validation.status"
+ >
+ <n-input
+ v-model:value="urlToParse"
+ placeholder="Your url to parse..."
+ />
+ </n-form-item>
+
+ <n-divider style="margin-top: 0;" />
+
+ <n-form>
+ <n-input-group
+ v-for="{title, key} in properties"
+ :key="key"
+ >
+ <n-input-group-label
+ style="flex: 0 0 120px;"
+ >
+ {{ title }}:
+ </n-input-group-label>
+ <input-copyable
+ :value="(urlParsed?.[key] as string) ?? ''"
+ readonly
+ placeholder=" "
+ />
+ </n-input-group>
+
+ <n-input-group
+ v-for="[k, v] in Object.entries(Object.fromEntries(urlParsed?.searchParams.entries() ?? []))"
+ :key="k"
+ >
+ <n-input-group-label
+ style="flex: 0 0 120px;"
+ >
+ <n-icon :component="SubdirectoryArrowRightRound" />
+ </n-input-group-label>
+ <input-copyable
+ :value="k"
+ readonly
+ />
+ <input-copyable
+ :value="v"
+ readonly
+ />
+ </n-input-group>
+ </n-form>
+ </n-card>
+</template>
+
+<script setup lang="ts">
+import { computed, ref } from 'vue';
+import { SubdirectoryArrowRightRound } from '@vicons/material';
+import InputCopyable from '../../components/InputCopyable.vue';
+import { useValidation } from '@/composable/validation';
+
+const urlToParse = ref('https://me:pwd@it-tools.tech:3000/url-parser?key1=value&key2=value2#the-hash')
+const urlParsed = computed<URL | undefined>(() => {
+ try {
+ return new URL(urlToParse.value)
+ } catch (_) {
+ return undefined
+ }
+})
+const validation = useValidation({source: urlToParse, rules: [
+ {validator: (value) => {
+ try {
+ new URL(value)
+ return true;
+ } catch (_) {
+ return false
+ }
+ }, message: 'Invalid url'}
+]})
+
+
+const properties: {title: string, key: keyof URL}[] = [
+ {title: 'Protocol', key: 'protocol'},
+ {title: 'Username', key: 'username'},
+ {title: 'Password', key: 'password'},
+ {title: 'Hostname', key: 'hostname'},
+ {title: 'Port', key: 'port'},
+ {title: 'Path', key: 'pathname'},
+ {title: 'Params', key: 'search'},
+]
+
+
+</script>
+
+<style lang="less" scoped>
+
+.n-input-group-label {
+ text-align: right;
+}
+.n-input-group {
+
+ &:not(:first-child) > * {
+
+ ::v-deep(.n-input__border), ::v-deep(.n-input-group-label__border) {
+ border-radius: 0;
+ border-top: none;
+
+ }
+ }
+
+ &:first-child > * {
+
+ ::v-deep(.n-input__border), ::v-deep(.n-input-group-label__border) {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+ }
+}
+</style> \ No newline at end of file