mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-11-01 04:23:50 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
072083832d | ||
|
|
c934c4e50c | ||
|
|
4a5734d4a3 | ||
|
|
f708f5091e | ||
|
|
db817a2459 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -2,6 +2,25 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [2.19.0](https://github.com/CorentinTh/it-tools/compare/v2.18.0...v2.19.0) (2023-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **new-tool:** keycode info ([c934c4e](https://github.com/CorentinTh/it-tools/commit/c934c4e50ca1a129b80b786a5d9a7dbc33ad9ba3))
|
||||
|
||||
## [2.18.0](https://github.com/CorentinTh/it-tools/compare/v2.17.0...v2.18.0) (2023-02-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **new-tool:** json minify ([#265](https://github.com/CorentinTh/it-tools/issues/265)) ([f708f50](https://github.com/CorentinTh/it-tools/commit/f708f5091e2182fc88e7cf3e7d23b3d05edc04da))
|
||||
|
||||
|
||||
### Refactors
|
||||
|
||||
* **tools:** config in query params ([db817a2](https://github.com/CorentinTh/it-tools/commit/db817a2459e23bd096274a7f91815d613d5f7ff4))
|
||||
|
||||
## [2.17.0](https://github.com/CorentinTh/it-tools/compare/v2.16.0...v2.17.0) (2023-01-13)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "it-tools",
|
||||
"version": "2.17.0",
|
||||
"version": "2.19.0",
|
||||
"description": "Collection of handy online tools for developers, with great UX. ",
|
||||
"keywords": [
|
||||
"productivity",
|
||||
@@ -37,6 +37,7 @@
|
||||
"@vicons/tabler": "^0.12.0",
|
||||
"@vueuse/core": "^8.9.4",
|
||||
"@vueuse/head": "^0.7.13",
|
||||
"@vueuse/router": "^9.11.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"change-case": "^4.1.2",
|
||||
"colord": "^2.9.3",
|
||||
|
||||
93
pnpm-lock.yaml
generated
93
pnpm-lock.yaml
generated
@@ -24,6 +24,7 @@ specifiers:
|
||||
'@vue/tsconfig': ^0.1.3
|
||||
'@vueuse/core': ^8.9.4
|
||||
'@vueuse/head': ^0.7.13
|
||||
'@vueuse/router': ^9.11.0
|
||||
bcryptjs: ^2.4.3
|
||||
c8: ^7.12.0
|
||||
change-case: ^4.1.2
|
||||
@@ -76,6 +77,7 @@ dependencies:
|
||||
'@vicons/tabler': 0.12.0
|
||||
'@vueuse/core': 8.9.4_vue@3.2.45
|
||||
'@vueuse/head': 0.7.13_vue@3.2.45
|
||||
'@vueuse/router': 9.11.0_xsxatmlnmmg5bcuv3xdnj6fj7y
|
||||
bcryptjs: 2.4.3
|
||||
change-case: 4.1.2
|
||||
colord: 2.9.3
|
||||
@@ -124,7 +126,7 @@ devDependencies:
|
||||
eslint: 8.27.0
|
||||
eslint-config-prettier: 8.5.0_eslint@8.27.0
|
||||
eslint-import-resolver-typescript: 3.5.2_dcpv4nbdr5ks2h5677xdltrk6e
|
||||
eslint-plugin-import: 2.26.0_eslint@8.27.0
|
||||
eslint-plugin-import: 2.26.0_gbipkkcbnjmysmpjttq6vkmfqq
|
||||
eslint-plugin-vue: 8.7.1_eslint@8.27.0
|
||||
jsdom: 19.0.0
|
||||
less: 4.1.3
|
||||
@@ -134,7 +136,7 @@ devDependencies:
|
||||
typescript: 4.5.5
|
||||
vite: 2.9.15_less@4.1.3
|
||||
vite-plugin-md: 0.12.4_vite@2.9.15
|
||||
vite-plugin-pwa: 0.11.13_vite@2.9.15
|
||||
vite-plugin-pwa: 0.11.13_7mbbuzxp22mje5bxdolj2b6yg4
|
||||
vite-svg-loader: 3.6.0
|
||||
vitest: 0.13.1_uwxj23d3xojfwkqpytqc7pyhry
|
||||
vue-tsc: 0.31.4_typescript@4.5.5
|
||||
@@ -2068,6 +2070,10 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
|
||||
eslint-plugin-vue: ^8.0.1
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 5.42.1_vfr6z4qvdp6defk3ked6x75zyi
|
||||
'@typescript-eslint/parser': 5.42.1_4rqwsplhh2ekz63wktwk7d7ht4
|
||||
@@ -2077,7 +2083,6 @@ packages:
|
||||
vue-eslint-parser: 8.3.0_eslint@8.27.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/@vue/reactivity-transform/3.2.45:
|
||||
@@ -2106,7 +2111,6 @@ packages:
|
||||
'@vue/runtime-core': 3.2.45
|
||||
'@vue/shared': 3.2.45
|
||||
csstype: 2.6.21
|
||||
dev: false
|
||||
|
||||
/@vue/server-renderer/3.2.45_vue@3.2.45:
|
||||
resolution: {integrity: sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==}
|
||||
@@ -2116,7 +2120,6 @@ packages:
|
||||
'@vue/compiler-ssr': 3.2.45
|
||||
'@vue/shared': 3.2.45
|
||||
vue: 3.2.45
|
||||
dev: false
|
||||
|
||||
/@vue/shared/3.2.45:
|
||||
resolution: {integrity: sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==}
|
||||
@@ -2173,6 +2176,19 @@ packages:
|
||||
resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==}
|
||||
dev: false
|
||||
|
||||
/@vueuse/router/9.11.0_xsxatmlnmmg5bcuv3xdnj6fj7y:
|
||||
resolution: {integrity: sha512-AlaQzbUy3XeqeoIapQxLvJjPzbdiO/Dt1thQhebP4iFUjc61a7WrboULxNBY+jEH0XipwK/T/b9mBnmn/jEStA==}
|
||||
peerDependencies:
|
||||
vue-router: '>=4.0.0-rc.1'
|
||||
dependencies:
|
||||
'@vueuse/shared': 9.11.0_vue@3.2.45
|
||||
vue-demi: 0.13.11_vue@3.2.45
|
||||
vue-router: 4.1.6_vue@3.2.45
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared/8.9.4_vue@3.2.45:
|
||||
resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==}
|
||||
peerDependencies:
|
||||
@@ -2188,6 +2204,15 @@ packages:
|
||||
vue-demi: 0.13.11_vue@3.2.45
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared/9.11.0_vue@3.2.45:
|
||||
resolution: {integrity: sha512-8lO7wD5abYxupKy2KynH1pSgP715ky6iCrWYb8aX2AuAVi9uHXj7qE1dw6BnmArSaLHci4x9iuzWPCpAzUkC/A==}
|
||||
dependencies:
|
||||
vue-demi: 0.13.11_vue@3.2.45
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared/9.5.0_vue@3.2.45:
|
||||
resolution: {integrity: sha512-HnnCWU1Vg9CVWRCcI8ohDKDRB2Sc4bTgT1XAIaoLSfVHHn+TKbrox6pd3klCSw4UDxkhDfOk8cAdcK+Z5KleCA==}
|
||||
dependencies:
|
||||
@@ -2861,8 +2886,8 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
is-text-path: 1.0.1
|
||||
JSONStream: 1.3.5
|
||||
is-text-path: 1.0.1
|
||||
lodash: 4.17.21
|
||||
meow: 8.1.2
|
||||
split2: 3.2.2
|
||||
@@ -2991,7 +3016,6 @@ packages:
|
||||
|
||||
/csstype/2.6.21:
|
||||
resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
|
||||
dev: false
|
||||
|
||||
/csstype/3.0.11:
|
||||
resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
|
||||
@@ -3030,12 +3054,22 @@ packages:
|
||||
|
||||
/debug/2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
dev: true
|
||||
|
||||
/debug/3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: true
|
||||
@@ -3574,6 +3608,8 @@ packages:
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
resolve: 1.22.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-import-resolver-typescript/3.5.2_dcpv4nbdr5ks2h5677xdltrk6e:
|
||||
@@ -3586,7 +3622,7 @@ packages:
|
||||
debug: 4.3.4
|
||||
enhanced-resolve: 5.10.0
|
||||
eslint: 8.27.0
|
||||
eslint-plugin-import: 2.26.0_eslint@8.27.0
|
||||
eslint-plugin-import: 2.26.0_gbipkkcbnjmysmpjttq6vkmfqq
|
||||
get-tsconfig: 4.2.0
|
||||
globby: 13.1.2
|
||||
is-core-module: 2.11.0
|
||||
@@ -3596,32 +3632,54 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-module-utils/2.7.4_eslint@8.27.0:
|
||||
/eslint-module-utils/2.7.4_idrr6ghswzssuopqxluk4kfum4:
|
||||
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': '*'
|
||||
eslint: '*'
|
||||
eslint-import-resolver-node: '*'
|
||||
eslint-import-resolver-typescript: '*'
|
||||
eslint-import-resolver-webpack: '*'
|
||||
peerDependenciesMeta:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
eslint:
|
||||
optional: true
|
||||
eslint-import-resolver-node:
|
||||
optional: true
|
||||
eslint-import-resolver-typescript:
|
||||
optional: true
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 5.42.1_4rqwsplhh2ekz63wktwk7d7ht4
|
||||
debug: 3.2.7
|
||||
eslint: 8.27.0
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-import-resolver-typescript: 3.5.2_dcpv4nbdr5ks2h5677xdltrk6e
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-import/2.26.0_eslint@8.27.0:
|
||||
/eslint-plugin-import/2.26.0_gbipkkcbnjmysmpjttq6vkmfqq:
|
||||
resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': '*'
|
||||
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
||||
peerDependenciesMeta:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 5.42.1_4rqwsplhh2ekz63wktwk7d7ht4
|
||||
array-includes: 3.1.6
|
||||
array.prototype.flat: 1.3.1
|
||||
debug: 2.6.9
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.27.0
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-module-utils: 2.7.4_eslint@8.27.0
|
||||
eslint-module-utils: 2.7.4_idrr6ghswzssuopqxluk4kfum4
|
||||
has: 1.0.3
|
||||
is-core-module: 2.11.0
|
||||
is-glob: 4.0.3
|
||||
@@ -3629,6 +3687,10 @@ packages:
|
||||
object.values: 1.1.6
|
||||
resolve: 1.22.1
|
||||
tsconfig-paths: 3.14.1
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-prettier/4.2.1_v7o5sx5x3wbs57ifz6wc4f76we:
|
||||
@@ -4834,6 +4896,8 @@ packages:
|
||||
mime: 1.6.0
|
||||
needle: 3.1.0
|
||||
source-map: 0.6.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/leven/3.1.0:
|
||||
@@ -5176,6 +5240,8 @@ packages:
|
||||
debug: 3.2.7
|
||||
iconv-lite: 0.6.3
|
||||
sax: 1.2.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
@@ -6542,7 +6608,6 @@ packages:
|
||||
resolution: {integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/uc.micro/1.0.6:
|
||||
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
|
||||
@@ -6699,10 +6764,11 @@ packages:
|
||||
vite: 2.9.15_less@4.1.3
|
||||
dev: true
|
||||
|
||||
/vite-plugin-pwa/0.11.13_vite@2.9.15:
|
||||
/vite-plugin-pwa/0.11.13_7mbbuzxp22mje5bxdolj2b6yg4:
|
||||
resolution: {integrity: sha512-Ssj14m3TRVLfkFEAWSMcFE2d1cSdEZyrVTzfY2lSL+umHYvcIFHVDAY143sygtBCb44OPczsAOmWwBTxwOvh7g==}
|
||||
peerDependencies:
|
||||
vite: ^2.0.0
|
||||
workbox-window: ^6.4.0
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
fast-glob: 3.2.12
|
||||
@@ -6968,7 +7034,6 @@ packages:
|
||||
'@vue/runtime-dom': 3.2.45
|
||||
'@vue/server-renderer': 3.2.45_vue@3.2.45
|
||||
'@vue/shared': 3.2.45
|
||||
dev: false
|
||||
|
||||
/vueuc/0.4.49_vue@3.2.45:
|
||||
resolution: {integrity: sha512-WarAC44a/Yx78CxkAgROYLq+LkAeCGA/6wHidVoFmHLbzyF3SiP2nzRNGD/8zJeJInXv18EnWK6A//eGgMMq8w==}
|
||||
|
||||
35
src/composable/queryParams.ts
Normal file
35
src/composable/queryParams.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useRouteQuery } from '@vueuse/router';
|
||||
import { computed } from 'vue';
|
||||
|
||||
export { useQueryParam };
|
||||
|
||||
const transformers = {
|
||||
number: {
|
||||
fromQuery: (value: string) => Number(value),
|
||||
toQuery: (value: number) => String(value),
|
||||
},
|
||||
string: {
|
||||
fromQuery: (value: string) => value,
|
||||
toQuery: (value: string) => value,
|
||||
},
|
||||
boolean: {
|
||||
fromQuery: (value: string) => value.toLowerCase() === 'true',
|
||||
toQuery: (value: boolean) => (value ? 'true' : 'false'),
|
||||
},
|
||||
};
|
||||
|
||||
function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue: T }) {
|
||||
const type = typeof defaultValue;
|
||||
const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;
|
||||
|
||||
const proxy = useRouteQuery(name, transformer.toQuery(defaultValue as never));
|
||||
|
||||
return computed<T>({
|
||||
get() {
|
||||
return transformer.fromQuery(proxy.value) as T;
|
||||
},
|
||||
set(value) {
|
||||
proxy.value = transformer.toQuery(value as never);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -40,6 +40,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useQueryParam } from '@/composable/queryParams';
|
||||
import { enc, lib, MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA3, SHA384, SHA512 } from 'crypto-js';
|
||||
import { ref } from 'vue';
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
@@ -59,7 +60,7 @@ const algos = {
|
||||
type AlgoNames = keyof typeof algos;
|
||||
type Encoding = keyof typeof enc | 'Bin';
|
||||
const algoNames = Object.keys(algos) as AlgoNames[];
|
||||
const encoding = ref<Encoding>('Hex');
|
||||
const encoding = useQueryParam<Encoding>({ defaultValue: 'Hex', name: 'encoding' });
|
||||
const clearText = ref('');
|
||||
|
||||
function formatWithEncoding(words: lib.WordArray, encoding: Encoding) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { tool as base64FileConverter } from './base64-file-converter';
|
||||
import { tool as base64StringConverter } from './base64-string-converter';
|
||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||
import { tool as keycodeInfo } from './keycode-info';
|
||||
import { tool as jsonMinify } from './json-minify';
|
||||
import { tool as bcrypt } from './bcrypt';
|
||||
import { tool as bip39 } from './bip39-generator';
|
||||
import { tool as caseConverter } from './case-converter';
|
||||
@@ -66,6 +68,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||
otpCodeGeneratorAndValidator,
|
||||
mimeTypes,
|
||||
jwtParser,
|
||||
keycodeInfo,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -74,7 +77,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||
},
|
||||
{
|
||||
name: 'Development',
|
||||
components: [gitMemo, randomPortGenerator, crontabGenerator, jsonViewer, sqlPrettify, chmodCalculator],
|
||||
components: [gitMemo, randomPortGenerator, crontabGenerator, jsonViewer, jsonMinify, sqlPrettify, chmodCalculator],
|
||||
},
|
||||
{
|
||||
name: 'Math',
|
||||
|
||||
11
src/tools/json-minify/index.ts
Normal file
11
src/tools/json-minify/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Braces } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'JSON minify',
|
||||
path: '/json-minify',
|
||||
description: 'Minify and compress your JSON by removing unnecessary white spaces.',
|
||||
keywords: ['json', 'minify', 'format'],
|
||||
component: () => import('./json-minify.vue'),
|
||||
icon: Braces,
|
||||
});
|
||||
57
src/tools/json-minify/json-minify.vue
Normal file
57
src/tools/json-minify/json-minify.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<n-form-item
|
||||
label="Your raw json"
|
||||
:feedback="rawJsonValidation.message"
|
||||
:validation-status="rawJsonValidation.status"
|
||||
>
|
||||
<n-input
|
||||
ref="inputElement"
|
||||
v-model:value="rawJson"
|
||||
placeholder="Paste your raw json here..."
|
||||
type="textarea"
|
||||
rows="20"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="Minify version of your JSON">
|
||||
<textarea-copyable :value="cleanJson" language="json" :follow-height-of="inputElement" />
|
||||
</n-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import JSON5 from 'json5';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const inputElement = ref<HTMLElement>();
|
||||
|
||||
const rawJson = ref('{\n\t"hello": [\n\t\t"world"\n\t]\n}');
|
||||
const cleanJson = computed(() => withDefaultOnError(() => JSON.stringify(JSON5.parse(rawJson.value), null, 0), ''));
|
||||
|
||||
const rawJsonValidation = useValidation({
|
||||
source: rawJson,
|
||||
rules: [
|
||||
{
|
||||
validator: (v) => v === '' || JSON5.parse(v),
|
||||
message: 'Provided JSON is not valid.',
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.result-card {
|
||||
position: relative;
|
||||
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
26
src/tools/keycode-info/index.ts
Normal file
26
src/tools/keycode-info/index.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Keyboard } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Keycode info',
|
||||
path: '/keycode-info',
|
||||
description: 'Find the javascript keycode, code, location and modifiers of any pressed key.',
|
||||
keywords: [
|
||||
'keycode',
|
||||
'info',
|
||||
'code',
|
||||
'javascript',
|
||||
'event',
|
||||
'keycodes',
|
||||
'which',
|
||||
'keyboard',
|
||||
'press',
|
||||
'modifier',
|
||||
'alt',
|
||||
'ctrl',
|
||||
'meta',
|
||||
'shift',
|
||||
],
|
||||
component: () => import('./keycode-info.vue'),
|
||||
icon: Keyboard,
|
||||
});
|
||||
67
src/tools/keycode-info/keycode-info.vue
Normal file
67
src/tools/keycode-info/keycode-info.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-card style="text-align: center; padding: 40px 0; margin-bottom: 26px">
|
||||
<n-h2 v-if="event">{{ event.key }}</n-h2>
|
||||
<n-text strong depth="3">Press the key on your keyboard you want to now stuff</n-text>
|
||||
</n-card>
|
||||
|
||||
<n-input-group v-for="({ label, value, placeholder }, i) of fields" :key="i" style="margin-bottom: 5px">
|
||||
<n-input-group-label style="flex: 0 0 150px"> {{ label }} </n-input-group-label>
|
||||
<input-copyable :value="value" readonly :placeholder="placeholder" />
|
||||
</n-input-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
import { computed, ref } from 'vue';
|
||||
import InputCopyable from '../../components/InputCopyable.vue';
|
||||
|
||||
const event = ref<KeyboardEvent>();
|
||||
|
||||
useEventListener(document, 'keydown', (e) => {
|
||||
event.value = e;
|
||||
});
|
||||
|
||||
const fields = computed(() => {
|
||||
if (!event.value) return [];
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'Key :',
|
||||
value: event.value.key,
|
||||
placeholder: 'Key name...',
|
||||
},
|
||||
{
|
||||
label: 'Keycode :',
|
||||
value: String(event.value.keyCode),
|
||||
placeholder: 'Keycode...',
|
||||
},
|
||||
{
|
||||
label: 'Code :',
|
||||
value: event.value.code,
|
||||
placeholder: 'Code...',
|
||||
},
|
||||
{
|
||||
label: 'Location :',
|
||||
value: String(event.value.location),
|
||||
placeholder: 'Code...',
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Modifiers :',
|
||||
value: [
|
||||
event.value.metaKey && 'Meta',
|
||||
event.value.shiftKey && 'Shift',
|
||||
event.value.ctrlKey && 'Ctrl',
|
||||
event.value.altKey && 'Alt',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' + '),
|
||||
placeholder: 'None',
|
||||
},
|
||||
];
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -54,18 +54,19 @@
|
||||
<script setup lang="ts">
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useQueryParam } from '@/composable/queryParams';
|
||||
import { createToken } from './token-generator.service';
|
||||
|
||||
const token = ref('');
|
||||
const length = ref(64);
|
||||
const length = useQueryParam({ name: 'length', defaultValue: 64 });
|
||||
const { copy } = useCopy({ source: token, text: 'Token copied to the clipboard' });
|
||||
|
||||
const withUppercase = ref(true);
|
||||
const withLowercase = ref(true);
|
||||
const withNumbers = ref(true);
|
||||
const withSymbols = ref(false);
|
||||
const withUppercase = useQueryParam({ name: 'uppercase', defaultValue: true });
|
||||
const withLowercase = useQueryParam({ name: 'lowercase', defaultValue: true });
|
||||
const withNumbers = useQueryParam({ name: 'numbers', defaultValue: true });
|
||||
const withSymbols = useQueryParam({ name: 'symbols', defaultValue: false });
|
||||
|
||||
watch([withUppercase, withLowercase, withNumbers, withSymbols, length], refreshToken);
|
||||
watch([withUppercase, withLowercase, withNumbers, withSymbols, length], refreshToken, { immediate: true });
|
||||
|
||||
function refreshToken() {
|
||||
token.value = createToken({
|
||||
@@ -76,6 +77,4 @@ function refreshToken() {
|
||||
withSymbols: withSymbols.value,
|
||||
});
|
||||
}
|
||||
|
||||
refreshToken();
|
||||
</script>
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import { ref, watch } from 'vue';
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
import { useQueryParam } from '@/composable/queryParams';
|
||||
|
||||
const count = ref(1);
|
||||
const count = useQueryParam({ defaultValue: 1, name: 'count' });
|
||||
|
||||
const uuids = ref('');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user