diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/index.ts | 3 | ||||
-rw-r--r-- | src/tools/url-parser/index.ts | 11 | ||||
-rw-r--r-- | src/tools/url-parser/url-parser.vue | 118 |
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 |