diff --git a/components.d.ts b/components.d.ts index b88ae981..af06dfb6 100644 --- a/components.d.ts +++ b/components.d.ts @@ -33,6 +33,7 @@ declare module '@vue/runtime-core' { CInputText: typeof import('./src/ui/c-input-text/c-input-text.vue')['default'] 'CInputText.demo': typeof import('./src/ui/c-input-text/c-input-text.demo.vue')['default'] CKeyValueList: typeof import('./src/ui/c-key-value-list/c-key-value-list.vue')['default'] + CKeyValueListItem: typeof import('./src/ui/c-key-value-list/c-key-value-list-item.vue')['default'] CLabel: typeof import('./src/ui/c-label/c-label.vue')['default'] CLink: typeof import('./src/ui/c-link/c-link.vue')['default'] 'CLink.demo': typeof import('./src/ui/c-link/c-link.demo.vue')['default'] diff --git a/package.json b/package.json index 977e31ef..53cb2815 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "plausible-tracker": "^0.3.8", "qrcode": "^1.5.1", "randombytes": "^2.1.0", - "sql-formatter": "^12.0.0", + "sql-formatter": "^13.0.0", "ua-parser-js": "^1.0.35", "unicode-emoji-json": "^0.4.0", "unplugin-auto-import": "^0.16.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af940199..74949501 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,8 +129,8 @@ dependencies: specifier: ^2.1.0 version: 2.1.0 sql-formatter: - specifier: ^12.0.0 - version: 12.0.0 + specifier: ^13.0.0 + version: 13.0.0 ua-parser-js: specifier: ^1.0.35 version: 1.0.35 @@ -5565,6 +5565,11 @@ packages: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} dev: true + /get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: false + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -6713,6 +6718,7 @@ packages: /nearley@2.20.1: resolution: {integrity: sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==} + hasBin: true dependencies: commander: 2.20.3 moo: 0.5.2 @@ -7820,10 +7826,12 @@ packages: resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} dev: false - /sql-formatter@12.0.0: - resolution: {integrity: sha512-LR2m7BEvkyNAPzmcSCZ2b4Qzm5ySiiXS9Juc73VguTqCWIbYv7ZFV4LaDM7jNNZqHPfrqFssO7WWpITsAuLOuQ==} + /sql-formatter@13.0.0: + resolution: {integrity: sha512-V21cVvge4rhn9Fa7K/fTKcmPM+x1yee6Vhq8ZwgaWh3VPBqApgsaoFB5kLAhiqRo5AmSaRyLU7LIdgnNwH01/w==} + hasBin: true dependencies: argparse: 2.0.1 + get-stdin: 8.0.0 nearley: 2.20.1 dev: false diff --git a/src/pages/Home.page.vue b/src/pages/Home.page.vue index 49d90c67..5c7c3c4f 100644 --- a/src/pages/Home.page.vue +++ b/src/pages/Home.page.vue @@ -49,7 +49,7 @@ const { t } = useI18n();
- {{ t('home.categories.newestTools', 'Newest tools') }} + {{ t('home.categories.newestTools') }} diff --git a/src/plugins/i18n.plugin.ts b/src/plugins/i18n.plugin.ts index c38cdee1..8e0b2d33 100644 --- a/src/plugins/i18n.plugin.ts +++ b/src/plugins/i18n.plugin.ts @@ -1,6 +1,22 @@ -import type { App } from 'vue'; +import type { Plugin } from 'vue'; import { createI18n } from 'vue-i18n'; -import messages from '@intlify/unplugin-vue-i18n/messages'; +import baseMessages from '@intlify/unplugin-vue-i18n/messages'; +import _ from 'lodash'; +import { parse as parseYaml } from 'yaml'; + +const i18nFiles = import.meta.glob('../tools/*/locales/**.yml', { as: 'raw' }); + +const messagesByTools = await Promise.all(_.map(i18nFiles, async (fileDescriptor, path) => { + const [, locale] = path.match(/\.\/tools\/.*?\/locales\/(.*)\.ya?ml$/i) ?? []; + const content = parseYaml(await fileDescriptor()); + + return { [locale]: content }; +})); + +const messages = _.merge( + baseMessages, + _.merge({}, ...messagesByTools), +); const i18n = createI18n({ legacy: false, @@ -8,8 +24,8 @@ const i18n = createI18n({ messages, }); -export const i18nPlugin = { - install: (app: App) => { +export const i18nPlugin: Plugin = { + install: (app) => { app.use(i18n); }, }; diff --git a/src/tools/iban-validator-and-parser/iban-validator-and-parser.e2e.spec.ts b/src/tools/iban-validator-and-parser/iban-validator-and-parser.e2e.spec.ts index 3501543f..c4a99860 100644 --- a/src/tools/iban-validator-and-parser/iban-validator-and-parser.e2e.spec.ts +++ b/src/tools/iban-validator-and-parser/iban-validator-and-parser.e2e.spec.ts @@ -1,14 +1,15 @@ import { type Page, expect, test } from '@playwright/test'; -import _ from 'lodash'; async function extractIbanInfo({ page }: { page: Page }) { - const tdHandles = await page.locator('table tr td').elementHandles(); - const tdTextContents = await Promise.all(tdHandles.map(el => el.textContent())); + const itemsLines = await page + .locator('.c-key-value-list__item').all(); - return _.chain(tdTextContents) - .map(tdTextContent => tdTextContent?.trim().replace(' Copy to clipboard', '')) - .chunk(2) - .value(); + return await Promise.all( + itemsLines.map(async item => [ + (await item.locator('.c-key-value-list__key').textContent() ?? '').trim(), + (await item.locator('.c-key-value-list__value').textContent() ?? '').trim(), + ]), + ); } test.describe('Tool - Iban validator and parser', () => { @@ -41,7 +42,7 @@ test.describe('Tool - Iban validator and parser', () => { expect(ibanInfo).toEqual([ ['Is IBAN valid ?', 'No'], - ['IBAN errors', 'Wrong account bank branch checksumWrong IBAN checksum Copy to clipboard'], + ['IBAN errors', 'Wrong account bank branch checksum Wrong IBAN checksum'], ['Is IBAN a QR-IBAN ?', 'No'], ['Country code', 'N/A'], ['BBAN', 'N/A'], diff --git a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue index d5cdc022..647be983 100644 --- a/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue +++ b/src/tools/iban-validator-and-parser/iban-validator-and-parser.vue @@ -60,7 +60,7 @@ const ibanExamples = [
- +
diff --git a/src/ui/c-key-value-list/c-key-value-list-item.vue b/src/ui/c-key-value-list/c-key-value-list-item.vue new file mode 100644 index 00000000..d21ef5d1 --- /dev/null +++ b/src/ui/c-key-value-list/c-key-value-list-item.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/ui/c-key-value-list/c-key-value-list.vue b/src/ui/c-key-value-list/c-key-value-list.vue index e3b19afd..d8a2b001 100644 --- a/src/ui/c-key-value-list/c-key-value-list.vue +++ b/src/ui/c-key-value-list/c-key-value-list.vue @@ -9,29 +9,13 @@ const formattedItems = computed(() => items.value.filter(item => !_.isNil(item.v diff --git a/src/ui/c-tooltip/c-tooltip.vue b/src/ui/c-tooltip/c-tooltip.vue index cc48fe1c..24c586b8 100644 --- a/src/ui/c-tooltip/c-tooltip.vue +++ b/src/ui/c-tooltip/c-tooltip.vue @@ -19,7 +19,10 @@ const isTargetHovered = useElementHover(targetRef); 'op-100 scale-100': isTargetHovered, }" > - + {{ tooltip }}
diff --git a/vite.config.ts b/vite.config.ts index 8e2e0836..00f90c33 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ runtimeOnly: true, compositionOnly: true, fullInstall: true, - include: [resolve(__dirname, 'locales/**'), resolve(__dirname, 'src/tools/*/locales/**')], + include: [resolve(__dirname, 'locales/**')], }), AutoImport({ imports: [ @@ -106,4 +106,7 @@ export default defineConfig({ test: { exclude: [...configDefaults.exclude, '**/*.e2e.spec.ts'], }, + build: { + target: 'esnext', + }, });