From 2816ed254aef1a3c5bf49eb5d824feb405fbe823 Mon Sep 17 00:00:00 2001 From: sharevb Date: Tue, 2 Apr 2024 08:52:27 +0200 Subject: [PATCH 1/3] feat(Hash Text): more hashing methods Added ADLER32, BLAKE2B, BLAKE2S, BLAKE3, CRC32, CRC32C, KECCAK, PBKDF2, SM3, WHIRLPOOL, XXHASH128, XXHASH3, XXHASH32, XXHASH64, Argon2, Argon2i, Argon2d, Argon2id Fix #728 and #641 and #362 --- package.json | 1 + pnpm-lock.yaml | 19 ++-- src/composable/queryParams.ts | 31 +++++- src/tools/hash-text/hash-text.vue | 164 +++++++++++++++++++++++++++++- src/tools/hash-text/index.ts | 21 +++- 5 files changed, 225 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index fd6c02e6..a4c236af 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "figlet": "^1.7.0", "figue": "^1.2.0", "fuse.js": "^6.6.2", + "hash-wasm": "^4.11.0", "highlight.js": "^11.7.0", "iarna-toml-esm": "^3.0.5", "ibantools": "^4.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd6c38c9..c9329a67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ dependencies: fuse.js: specifier: ^6.6.2 version: 6.6.2 + hash-wasm: + specifier: ^4.11.0 + version: 4.11.0 highlight.js: specifier: ^11.7.0 version: 11.7.0 @@ -3351,7 +3354,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.7.2(vue@3.3.4) + '@vueuse/shared': 10.9.0(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3993,10 +3996,10 @@ packages: - vue dev: false - /@vueuse/shared@10.7.2(vue@3.3.4): - resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} + /@vueuse/shared@10.9.0(vue@3.3.4): + resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} dependencies: - vue-demi: 0.14.6(vue@3.3.4) + vue-demi: 0.14.7(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5969,6 +5972,10 @@ packages: function-bind: 1.1.2 dev: true + /hash-wasm@4.11.0: + resolution: {integrity: sha512-HVusNXlVqHe0fzIzdQOGolnFN6mX/fqcrSAOcTBXdvzrXVHwTz11vXeKRmkR5gTuwVpvHZEIyKoePDvuAR+XwQ==} + dev: false + /hasown@2.0.0: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} @@ -9151,8 +9158,8 @@ packages: vue: 3.3.4 dev: false - /vue-demi@0.14.6(vue@3.3.4): - resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + /vue-demi@0.14.7(vue@3.3.4): + resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true requiresBuild: true diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9699abbc..9e184610 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -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: { @@ -33,3 +34,31 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }, }); } + +function useQueryParamOrStorage({ 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 storageDefaultValue = storageRef.value ?? defaultValue; + + const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never)); + + const ref = computed({ + get() { + return transformer.fromQuery(proxy.value) as unknown as T; + }, + set(value) { + proxy.value = transformer.toQuery(value as never); + }, + }); + + watch( + ref, + (newValue) => { + storageRef.value = newValue; + }, + ); + + return ref; +} diff --git a/src/tools/hash-text/hash-text.vue b/src/tools/hash-text/hash-text.vue index 6eae9818..c6466f20 100644 --- a/src/tools/hash-text/hash-text.vue +++ b/src/tools/hash-text/hash-text.vue @@ -2,9 +2,30 @@ import type { lib } from 'crypto-js'; import { MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA3, SHA384, SHA512, enc } from 'crypto-js'; +import { + adler32, + argon2d, + argon2i, + argon2id, + blake2b, + blake2s, + blake3, + crc32, + crc32c, + createSHA256, + keccak, + pbkdf2, + sm3, + whirlpool, + xxhash128, + xxhash3, + xxhash32, + xxhash64, +} from 'hash-wasm'; + import InputCopyable from '../../components/InputCopyable.vue'; import { convertHexToBin } from './hash-text.service'; -import { useQueryParam } from '@/composable/queryParams'; +import { useQueryParamOrStorage } from '@/composable/queryParams'; const algos = { MD5, @@ -20,7 +41,27 @@ const algos = { type AlgoNames = keyof typeof algos; type Encoding = keyof typeof enc | 'Bin'; const algoNames = Object.keys(algos) as AlgoNames[]; -const encoding = useQueryParam({ defaultValue: 'Hex', name: 'encoding' }); + +const algosWasm = { + adler32, + crc32, + crc32c, + blake2b, + blake2s, + blake3, + keccak, + xxhash32, + xxhash64, + xxhash3, + xxhash128, + sm3, + whirlpool, +} as const; + +type AlgoWasmNames = keyof typeof algosWasm; +const algoWasmNames = Object.keys(algosWasm) as AlgoWasmNames[]; + +const encoding = useQueryParamOrStorage({ defaultValue: 'Hex', storageName: 'hash-text:encoding', name: 'encoding' }); const clearText = ref(''); function formatWithEncoding(words: lib.WordArray, encoding: Encoding) { @@ -32,12 +73,91 @@ function formatWithEncoding(words: lib.WordArray, encoding: Encoding) { } const hashText = (algo: AlgoNames, value: string) => formatWithEncoding(algos[algo](value), encoding.value); + +const defaultHashWasmValues = { + adler32: '', + crc32: '', + crc32c: '', + blake2b: '', + blake2s: '', + blake3: '', + keccak: '', + xxhash32: '', + xxhash64: '', + xxhash3: '', + xxhash128: '', + sm3: '', + whirlpool: '', +}; +const hashWasmValues = computedAsync(async () => { + const encodingValue = encoding.value; + const clearTextValue = clearText.value; + const ret = defaultHashWasmValues; + for (const algo of algoWasmNames) { + ret[algo] = formatWithEncoding(enc.Hex.parse(await algosWasm[algo](clearTextValue)), encodingValue); + } + return ret; +}, defaultHashWasmValues); + +const salt = new Uint8Array(16); +window.crypto.getRandomValues(salt); +const hashWasmArgon2i = computedAsync(async () => { + const clearTextValue = clearText.value; + return await argon2i({ + password: clearTextValue, + salt, + parallelism: 1, + memorySize: 128, + iterations: 4, + hashLength: 16, + outputType: 'encoded', + }); +}); +const hashWasmArgon2d = computedAsync(async () => { + const clearTextValue = clearText.value; + return await argon2d({ + password: clearTextValue, + salt, + parallelism: 1, + memorySize: 128, + iterations: 4, + hashLength: 16, + outputType: 'encoded', + }); +}); +const hashWasmArgon2id = computedAsync(async () => { + const clearTextValue = clearText.value; + return await argon2id({ + password: clearTextValue, + salt, + parallelism: 1, + memorySize: 128, + iterations: 4, + hashLength: 16, + outputType: 'encoded', + }); +}); +const hashWasmPBKDF2 = computedAsync(async () => { + const clearTextValue = clearText.value; + return await pbkdf2({ + password: clearTextValue, + salt, + iterations: 16, + hashLength: 32, + hashFunction: createSHA256(), + }); +}); diff --git a/src/tools/hash-text/index.ts b/src/tools/hash-text/index.ts index 2070e41d..d214cf97 100644 --- a/src/tools/hash-text/index.ts +++ b/src/tools/hash-text/index.ts @@ -5,7 +5,8 @@ import { translate } from '@/plugins/i18n.plugin'; export const tool = defineTool({ name: translate('tools.hash-text.title'), path: '/hash-text', - description: translate('tools.hash-text.description'), + description: + 'Hash a text string using the function you need : MD5, SHA1, SHA256, SHA224, SHA512, SHA384, SHA3, RIPEMD160, ADLER32, CRC32, CRC32C, BLAKE, KECCAK, XXHASH, SM3, WHIRLPOOL or Argon2(i/d/id)', keywords: [ 'hash', 'digest', @@ -20,6 +21,24 @@ export const tool = defineTool({ 'SHA384', 'SHA3', 'RIPEMD160', + 'ADLER32', + 'BLAKE2B', + 'BLAKE2S', + 'BLAKE3', + 'CRC32', + 'CRC32C', + 'KECCAK', + 'PBKDF2', + 'SM3', + 'WHIRLPOOL', + 'XXHASH128', + 'XXHASH3', + 'XXHASH32', + 'XXHASH64', + 'Argon2', + 'Argon2i', + 'Argon2d', + 'Argon2id', ], component: () => import('./hash-text.vue'), icon: EyeOff, From e60cee96828e4848983f3aea40a33122f667d0b5 Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sat, 6 Apr 2024 11:56:09 +0200 Subject: [PATCH 2/3] chore(github workflows): ci and e2e tests: try updating to node 20 --- .github/workflows/ci.yml | 2 +- .github/workflows/e2e-tests.yml | 2 +- playwright.config.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5c67208..4dd9ffb7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - run: corepack enable - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: 'pnpm' - name: Install dependencies diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index b5b04096..13b787ef 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20 cache: 'pnpm' - name: Get Playwright version diff --git a/playwright.config.ts b/playwright.config.ts index 3caa0612..5257c526 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -9,7 +9,7 @@ const useWebServer = process.env.NO_WEB_SERVER !== 'true'; */ export default defineConfig({ testDir: './src', - testMatch: /.*\.e2e\.(spec\.)?ts/, + testMatch: /\.e2e\.(spec\.)?ts$/, /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ @@ -57,7 +57,7 @@ export default defineConfig({ && { webServer: { command: 'npm run preview', - url: 'http://127.0.0.1:5050', + url: 'http://localhost:5050', reuseExistingServer: !isCI, }, } From 8a3b106d96c6225622cbd61241a71359fa855b2e Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 14 Jul 2024 23:11:37 +0200 Subject: [PATCH 3/3] fix: update queryParams --- pnpm-lock.yaml | 171 +++++++++++++++++++--------------- src/composable/queryParams.ts | 34 +++---- 2 files changed, 113 insertions(+), 92 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f42d7b43..1c9e072f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3357,7 +3357,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.9.0(vue@3.3.4) + '@vueuse/shared': 10.11.0(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3990,20 +3990,19 @@ packages: - vue dev: false - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} + /@vueuse/shared@10.11.0(vue@3.3.4): + resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==} dependencies: - vue-demi: 0.14.5(vue@3.3.4) + vue-demi: 0.14.8(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.9.0(vue@3.3.4): - resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} + /@vueuse/shared@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} dependencies: - vue-demi: 0.14.7(vue@3.3.4) - vue-demi: 0.14.7(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -4120,7 +4119,7 @@ packages: /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-array-buffer: 3.0.2 dev: true @@ -4134,10 +4133,10 @@ packages: engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 dev: true @@ -4304,12 +4303,15 @@ packages: engines: {node: '>=8'} dev: true - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.1.1 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 dev: true /callsites@3.1.0: @@ -4822,13 +4824,13 @@ packages: clone: 1.0.4 dev: true - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.1 dev: true /define-lazy-prop@2.0.0: @@ -4840,8 +4842,8 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 dev: true @@ -5031,15 +5033,15 @@ packages: array-buffer-byte-length: 1.0.0 arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 has-proto: 1.0.1 has-symbols: 1.0.3 hasown: 2.0.0 @@ -5069,11 +5071,23 @@ packages: which-typed-array: 1.1.13 dev: true + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + /es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 has-tostringtag: 1.0.0 hasown: 2.0.0 dev: true @@ -5754,7 +5768,7 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 @@ -5782,9 +5796,11 @@ packages: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} dev: true - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 @@ -5809,8 +5825,8 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /get-tsconfig@4.7.2: @@ -5905,7 +5921,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 dev: true /graceful-fs@4.2.11: @@ -5946,10 +5962,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 dev: true /has-proto@1.0.1: @@ -6175,9 +6191,9 @@ packages: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 hasown: 2.0.0 - side-channel: 1.0.4 + side-channel: 1.0.6 dev: true /ip-address@7.1.0: @@ -6210,8 +6226,8 @@ packages: /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 dev: true @@ -6235,7 +6251,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.0 dev: true @@ -6372,7 +6388,7 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.0 dev: true @@ -6384,7 +6400,7 @@ packages: /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-stream@2.0.1: @@ -6427,7 +6443,7 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-what@3.14.1: @@ -7138,7 +7154,7 @@ packages: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -7790,7 +7806,7 @@ packages: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 set-function-name: 2.0.1 dev: true @@ -7941,8 +7957,8 @@ packages: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -7954,8 +7970,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-regex: 1.1.4 dev: true @@ -8045,23 +8061,25 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: false - /set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true /set-value@4.1.0: @@ -8084,11 +8102,13 @@ packages: engines: {node: '>=8'} dev: true - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 object-inspect: 1.13.1 dev: true @@ -8239,22 +8259,22 @@ packages: /string.prototype.matchall@4.0.10: resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 internal-slot: 1.0.6 regexp.prototype.flags: 1.5.1 set-function-name: 2.0.1 - side-channel: 1.0.4 + side-channel: 1.0.6 dev: true /string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 dev: true @@ -8262,7 +8282,7 @@ packages: /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 dev: true @@ -8270,7 +8290,7 @@ packages: /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 dev: true @@ -8567,8 +8587,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 dev: true @@ -8576,7 +8596,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -8587,7 +8607,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -8596,7 +8616,7 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 is-typed-array: 1.1.12 dev: true @@ -8632,7 +8652,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -9166,10 +9186,8 @@ packages: vue: 3.3.4 dev: false - /vue-demi@0.14.7(vue@3.3.4): - resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} - /vue-demi@0.14.7(vue@3.3.4): - resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} + /vue-demi@0.14.8(vue@3.3.4): + resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true @@ -9353,7 +9371,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 @@ -9459,6 +9477,7 @@ packages: /workbox-google-analytics@7.0.0: resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} + deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained dependencies: workbox-background-sync: 7.0.0 workbox-core: 7.0.0 diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9e184610..7cc8cc0d 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -17,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({ name, defaultValue }: { name: string; defaultValue: T }) { @@ -35,30 +41,26 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }); } -function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue?: T }) { +function useQueryParamOrStorage({ 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 storageDefaultValue = storageRef.value ?? defaultValue; + const proxyDefaultValue = transformer.toQuery(defaultValue as never); + const proxy = useRouteQuery(name, proxyDefaultValue); - const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never)); + const r = ref(defaultValue); - const ref = computed({ - get() { - return transformer.fromQuery(proxy.value) as unknown as T; - }, - set(value) { + watch(r, + (value) => { proxy.value = transformer.toQuery(value as never); + storageRef.value = value as never; }, - }); + { deep: true }); - watch( - ref, - (newValue) => { - storageRef.value = newValue; - }, - ); + r.value = (proxy.value && proxy.value !== proxyDefaultValue + ? transformer.fromQuery(proxy.value) as unknown as T + : storageRef.value as T) as never; - return ref; + return r; }