Skip to content

Commit

Permalink
Merge branch 'main' into feat/timezone-converter
Browse files Browse the repository at this point in the history
  • Loading branch information
sharevb committed Sep 21, 2024
2 parents 616e5c9 + f5c4ab1 commit ecbd65c
Show file tree
Hide file tree
Showing 18 changed files with 651 additions and 4 deletions.
Binary file added .github/logo-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/logo-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed .github/logo.png
Binary file not shown.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
![logo](.github/logo.png)
<picture>
<source srcset="./.github/logo-dark.png" media="(prefers-color-scheme: light)">
<source srcset="./.github/logo-white.png" media="(prefers-color-scheme: dark)">
<img src="./.github/logo-dark.png" alt="logo">
</picture>

Useful tools for developer and people working in IT. [Have a look !](https://it-tools.tech).

Expand Down
3 changes: 3 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ declare module '@vue/runtime-core' {
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default']
'RegexMemo.content': typeof import('./src/tools/regex-memo/regex-memo.content.md')['default']
RegexTester: typeof import('./src/tools/regex-tester/regex-tester.vue')['default']
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@
"dependencies": {
"@it-tools/bip39": "^0.0.4",
"@it-tools/oggen": "^1.3.0",
"@regexper/render": "^1.0.0",
"@sindresorhus/slugify": "^2.2.1",
"@tiptap/pm": "2.1.6",
"@tiptap/starter-kit": "2.1.6",
"@tiptap/vue-3": "2.0.3",
"@types/markdown-it": "^13.0.7",
"@types/figlet": "^1.5.8",
"@types/markdown-it": "^13.0.7",
"@vicons/material": "^0.12.0",
"@vicons/tabler": "^0.12.0",
"@vueuse/core": "^10.3.0",
Expand Down Expand Up @@ -86,6 +87,7 @@
"pinia": "^2.0.34",
"plausible-tracker": "^0.3.8",
"qrcode": "^1.5.1",
"randexp": "^0.5.3",
"sql-formatter": "^13.0.0",
"ua-parser-js": "^1.0.35",
"ulid": "^2.3.0",
Expand All @@ -95,6 +97,7 @@
"vue": "^3.3.4",
"vue-i18n": "^9.9.1",
"vue-router": "^4.1.6",
"vue-shadow-dom": "^4.2.0",
"vue-tsc": "^1.8.1",
"xml-formatter": "^3.3.2",
"xml-js": "^1.6.11",
Expand Down
46 changes: 46 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion src/composable/queryParams.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useRouteQuery } from '@vueuse/router';
import { computed } from 'vue';
import { useStorage } from '@vueuse/core';

export { useQueryParam };
export { useQueryParam, useQueryParamOrStorage };

const transformers = {
number: {
Expand All @@ -16,6 +17,12 @@ const transformers = {
fromQuery: (value: string) => value.toLowerCase() === 'true',
toQuery: (value: boolean) => (value ? 'true' : 'false'),
},
object: {
fromQuery: (value: string) => {
return JSON.parse(value);
},
toQuery: (value: object) => JSON.stringify(value),
},
};

function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue: T }) {
Expand All @@ -33,3 +40,27 @@ function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue:
},
});
}

function useQueryParamOrStorage<T>({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) {
const type = typeof defaultValue;
const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;

const storageRef = useStorage(storageName, defaultValue);
const proxyDefaultValue = transformer.toQuery(defaultValue as never);
const proxy = useRouteQuery(name, proxyDefaultValue);

const r = ref(defaultValue);

watch(r,
(value) => {
proxy.value = transformer.toQuery(value as never);
storageRef.value = value as never;
},
{ deep: true });

r.value = (proxy.value && proxy.value !== proxyDefaultValue
? transformer.fromQuery(proxy.value) as unknown as T
: storageRef.value as T) as never;

return r;
}
19 changes: 18 additions & 1 deletion src/composable/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import _ from 'lodash';
import { type Ref, reactive, watch } from 'vue';

type ValidatorReturnType = unknown;
type GetErrorMessageReturnType = string;

export interface UseValidationRule<T> {
validator: (value: T) => ValidatorReturnType
getErrorMessage?: (value: T) => GetErrorMessageReturnType
message: string
}

Expand All @@ -24,6 +26,15 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean {
}
}

export function getErrorMessageOrThrown(cb: () => GetErrorMessageReturnType): string {
try {
return cb() || '';
}
catch (e: any) {
return e.toString();
}
}

export interface ValidationAttrs {
feedback: string
validationStatus: string | undefined
Expand Down Expand Up @@ -61,7 +72,13 @@ export function useValidation<T>({

for (const rule of get(rules)) {
if (isFalsyOrHasThrown(() => rule.validator(source.value))) {
state.message = rule.message;
if (rule.getErrorMessage) {
const getErrorMessage = rule.getErrorMessage;
state.message = rule.message.replace('{0}', getErrorMessageOrThrown(() => getErrorMessage(source.value)));
}
else {
state.message = rule.message;
}
state.status = 'error';
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createPinia } from 'pinia';
import { createHead } from '@vueuse/head';

import { registerSW } from 'virtual:pwa-register';
import shadow from 'vue-shadow-dom';
import { plausible } from './plugins/plausible.plugin';

import 'virtual:uno.css';
Expand All @@ -23,5 +24,6 @@ app.use(i18nPlugin);
app.use(router);
app.use(naive);
app.use(plausible);
app.use(shadow);

app.mount('#app');
4 changes: 4 additions & 0 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { tool as safelinkDecoder } from './safelink-decoder';
import { tool as xmlToJson } from './xml-to-json';
import { tool as jsonToXml } from './json-to-xml';
import { tool as timezoneConverter } from './timezone-converter';
import { tool as regexTester } from './regex-tester';
import { tool as regexMemo } from './regex-memo';
import { tool as markdownToHtml } from './markdown-to-html';
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
import { tool as numeronymGenerator } from './numeronym-generator';
Expand Down Expand Up @@ -158,6 +160,8 @@ export const toolsByCategory: ToolCategory[] = [
xmlFormatter,
yamlViewer,
emailNormalizer,
regexTester,
regexMemo,
],
},
{
Expand Down
12 changes: 12 additions & 0 deletions src/tools/regex-memo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BrandJavascript } from '@vicons/tabler';
import { defineTool } from '../tool';

export const tool = defineTool({
name: 'Regex cheatsheet',
path: '/regex-memo',
description: 'Javascript Regex/Regular Expression cheatsheet',
keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'],
component: () => import('./regex-memo.vue'),
icon: BrandJavascript,
createdAt: new Date('2024-09-20'),
});
Loading

0 comments on commit ecbd65c

Please sign in to comment.