diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 00000000..afe99f6b --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "context7": { + "httpUrl": "https://mcp.context7.com/mcp", + "headers": { + "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}", + "Accept": "application/json, text/event-stream" + } + } + }, + "context": { + "fileName": ["AGENTS.md"] + } +} diff --git a/.gitignore b/.gitignore index 1e796700..e12d820e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ node_modules .DS_Store components.d.ts auto-imports.d.ts -.github/*-instructions.md \ No newline at end of file +.github/*-instructions.md +.env \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..5dbd727a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,199 @@ +# massCode AI Coding Guidelines + +You are an expert Senior Frontend Developer specializing in Electron, Vue 3, and TypeScript. +Follow these rules strictly when generating code for massCode. + +## 1. Core Stack + +- **Framework:** Vue 3 (Composition API, ` + + +``` + +**Data Fetching (Renderer):** + +```typescript +import { api } from '~/renderer/services/api' +const { data } = await api.snippets.getSnippets({ folderId: 1 }) +``` + +**IPC Call:** + +```typescript +import { ipc } from '@/electron' +await ipc.invoke('fs:assets', { buffer, fileName }) +``` + +**Localization:** + +```html + + + +``` + +**Creating New API Endpoint (DTO & Route):** + +1. **Define DTO** (`src/main/api/dto/snippets.ts`): + + ```typescript + import { t } from 'elysia' + + // Define validation schema + const snippetsDuplicate = t.Object({ + id: t.Number() + }) + + // Register in main DTO model + export const snippetsDTO = new Elysia().model({ + // ... other DTOs + snippetsDuplicate + }) + ``` + +2. **Add Route** (`src/main/api/routes/snippets.ts`): + + ```typescript + import { useDB } from '../../db' + + app.post('/duplicate', ({ body }) => { + const db = useDB() + // Database logic here... + return { id: newId } + }, { + body: 'snippetsDuplicate', // Use registered DTO name + detail: { tags: ['Snippets'] } + }) + ``` + +3. **Generate Client:** Run `pnpm api:generate` diff --git a/CHANGELOG.md b/CHANGELOG.md index ed7924d5..9fd5097b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +# [4.3.0](https://github.com/massCodeIO/massCode/compare/v4.2.2...v4.3.0) (2025-11-26) + + +### Bug Fixes + +* **folders:** ensure context and toolbar folder creation respect parent ([#640](https://github.com/massCodeIO/massCode/issues/640)) ([b2877c2](https://github.com/massCodeIO/massCode/commit/b2877c29994f4c227da967e801dc13d3731aeba0)) + + +### Features + +* **editor:** add Power Query (M) language support ([#639](https://github.com/massCodeIO/massCode/issues/639)) ([a49b5d0](https://github.com/massCodeIO/massCode/commit/a49b5d04ab28cd1bc163a24f8b8c431c72baa6f5)) +* **folders:** add multi-selection ([#641](https://github.com/massCodeIO/massCode/issues/641)) ([daef94f](https://github.com/massCodeIO/massCode/commit/daef94f718fd7ec9611f8c21a618c8a33f833feb)) +* **preferences:** add api port to preference option ([#631](https://github.com/massCodeIO/massCode/issues/631)) ([d542824](https://github.com/massCodeIO/massCode/commit/d542824361becdcfcd7bd980adff8a7f8f0354ce)) + + + ## [4.2.2](https://github.com/massCodeIO/massCode/compare/v4.2.1...v4.2.2) (2025-10-29) diff --git a/package.json b/package.json index f54f4f25..84309e6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "masscode", - "version": "4.3.0", + "version": "4.4.0", "description": "A free and open source code snippets manager for developers", "author": { "name": "Anton Reshetov", @@ -41,8 +41,10 @@ "dependencies": { "@dagrejs/dagre": "^1.1.5", "@elysiajs/cors": "^1.2.0", - "@elysiajs/node": "^1.2.5", - "@elysiajs/swagger": "^1.2.2", + "@elysiajs/node": "^1.4.2", + "@elysiajs/swagger": "^1.3.1", + "@faker-js/faker": "^10.1.0", + "@sinclair/typebox": "^0.34.41", "@vue-flow/background": "^1.3.2", "@vue-flow/controls": "^1.1.3", "@vue-flow/core": "^1.46.5", @@ -60,7 +62,7 @@ "date-fns": "^4.1.0", "dom-to-image": "^2.6.0", "electron-store": "^8.2.0", - "elysia": "^1.2.15", + "elysia": "^1.4.16", "fs-extra": "^11.3.0", "i18next": "^24.2.2", "i18next-fs-backend": "^2.6.0", @@ -84,7 +86,8 @@ "toml": "^3.0.0", "uuid": "^11.1.0", "vue-sonner": "^1.3.0", - "vue3-perfect-scrollbar": "^2.0.0" + "vue3-perfect-scrollbar": "^2.0.0", + "vuedraggable": "^4.1.0" }, "devDependencies": { "@antfu/eslint-config": "^3.16.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c423995e..20c3a5c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,13 +13,19 @@ importers: version: 1.1.5 '@elysiajs/cors': specifier: ^1.2.0 - version: 1.2.0(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3)) + version: 1.2.0(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3)) '@elysiajs/node': - specifier: ^1.2.5 - version: 1.2.5(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3))(formidable@3.5.2)(ws@8.18.1) + specifier: ^1.4.2 + version: 1.4.2(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3)) '@elysiajs/swagger': - specifier: ^1.2.2 - version: 1.2.2(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3)) + specifier: ^1.3.1 + version: 1.3.1(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3)) + '@faker-js/faker': + specifier: ^10.1.0 + version: 10.1.0 + '@sinclair/typebox': + specifier: ^0.34.41 + version: 0.34.41 '@vue-flow/background': specifier: ^1.3.2 version: 1.3.2(@vue-flow/core@1.46.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3)) @@ -72,8 +78,8 @@ importers: specifier: ^8.2.0 version: 8.2.0 elysia: - specifier: ^1.2.15 - version: 1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3) + specifier: ^1.4.16 + version: 1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3) fs-extra: specifier: ^11.3.0 version: 11.3.0 @@ -146,6 +152,9 @@ importers: vue3-perfect-scrollbar: specifier: ^2.0.0 version: 2.0.0(vue@3.5.13(typescript@5.7.3)) + vuedraggable: + specifier: ^4.1.0 + version: 4.1.0(vue@3.5.13(typescript@5.7.3)) devDependencies: '@antfu/eslint-config': specifier: ^3.16.0 @@ -352,6 +361,9 @@ packages: resolution: {integrity: sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==} engines: {node: '>=6.9.0'} + '@borewit/text-codec@0.1.1': + resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} + '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} @@ -499,21 +511,15 @@ packages: peerDependencies: elysia: '>= 1.2.0' - '@elysiajs/node@1.2.5': - resolution: {integrity: sha512-g5iE2csoixsx4KT4Q57BVjQqjcjJPigWF1ruGHguxrwmI/nfTlWNnpKAR6XU+MERhr3Cf7dd6GI826BBNgo0xw==} + '@elysiajs/node@1.4.2': + resolution: {integrity: sha512-zqeBAV4/faCcmIEjCp3g6jRwsbaWsd5HqmlEf3CirD9HkTWQNo4T+GN/qGZi7zgd84D3Kzxsny7ZTMXEfrDSXQ==} peerDependencies: - bufferutil: '>= 4.0.1' - elysia: '>= 1.2.7' - formidable: '>= 3.5.2' - ws: '>= 8.18.0' - peerDependenciesMeta: - bufferutil: - optional: true + elysia: '>= 1.4.0' - '@elysiajs/swagger@1.2.2': - resolution: {integrity: sha512-DG0PbX/wzQNQ6kIpFFPCvmkkWTIbNWDS7lVLv3Puy6ONklF14B4NnbDfpYjX1hdSYKeCqKBBOuenh6jKm8tbYA==} + '@elysiajs/swagger@1.3.1': + resolution: {integrity: sha512-LcbLHa0zE6FJKWPWKsIC/f+62wbDv3aXydqcNPVPyqNcaUgwvCajIi+5kHEU6GO3oXUCpzKaMsb3gsjt8sLzFQ==} peerDependencies: - elysia: '>= 1.2.0' + elysia: '>= 1.3.0' '@es-joy/jsdoccomment@0.49.0': resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} @@ -726,6 +732,10 @@ packages: resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@faker-js/faker@10.1.0': + resolution: {integrity: sha512-C3mrr3b5dRVlKPJdfrAXS8+dq+rq8Qm5SNRazca0JKgw1HQERFmrVb0towvMmw5uu8hHKNiQasMaR/tydf3Zsg==} + engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} + '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -1023,8 +1033,8 @@ packages: resolution: {integrity: sha512-q01ctijmHArM5KOny2zU+sHfhpsgOAENrDENecK2TsQNn5FYLmFZouMKeW2M6F7KFLPZnFxUiL/rT88b6Rp/Kg==} engines: {node: '>=18'} - '@sinclair/typebox@0.34.27': - resolution: {integrity: sha512-C7mxE1VC3WC2McOufZXEU48IfRVI+BcKxk4NOyNn3+JMUNdJHEWGS5CqjuDX+ij2NCCz8/nse1mT7yn8Fv2GHg==} + '@sinclair/typebox@0.34.41': + resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} @@ -1132,6 +1142,13 @@ packages: peerDependencies: vue: ^2.7.0 || ^3.0.0 + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -1601,9 +1618,6 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} @@ -2012,6 +2026,14 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.4.1: + resolution: {integrity: sha512-E7WKBcHVhAVrY6JYD5kteNqVq1GSZxqGrdSiwXR9at+XHi43HJoCQKXcCczR5LBnBquFZPsB3o7HklulKoBU5w==} + peerDependencies: + srvx: '>=0.7.1' + peerDependenciesMeta: + srvx: + optional: true + crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} @@ -2217,6 +2239,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -2285,9 +2316,6 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - dir-compare@4.2.0: resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} @@ -2374,14 +2402,17 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - elysia@1.2.15: - resolution: {integrity: sha512-/oUSNb83jIWAGi6uSmbQ7Uy0RSJ9NimbVToSLnYS8jjsGId3zgdHqprsdf4rIMInOmEM8skjsFhZ4x8C5AB6+w==} + elysia@1.4.16: + resolution: {integrity: sha512-KZtKN160/bdWVKg2hEgyoNXY8jRRquc+m6PboyisaLZL891I+Ufb7Ja6lDAD7vMQur8sLEWIcidZOzj5lWw9UA==} peerDependencies: - '@sinclair/typebox': '>= 0.34.0' + '@sinclair/typebox': '>= 0.34.0 < 1' + '@types/bun': '>= 1.2.0' + exact-mirror: '>= 0.0.9' + file-type: '>= 20.0.0' openapi-types: '>= 12.0.0' typescript: '>= 5.0.0' peerDependenciesMeta: - openapi-types: + '@types/bun': optional: true typescript: optional: true @@ -2654,6 +2685,14 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + exact-mirror@0.2.5: + resolution: {integrity: sha512-u8Wu2lO8nio5lKSJubOydsdNtQmH8ENba5m0nbQYmTvsjksXKYIS1nSShdDlO8Uem+kbo+N6eD5I03cpZ+QsRQ==} + peerDependencies: + '@sinclair/typebox': ^0.34.15 + peerDependenciesMeta: + '@sinclair/typebox': + optional: true + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -2665,6 +2704,9 @@ packages: exponential-backoff@3.1.2: resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -2674,6 +2716,9 @@ packages: resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} engines: {'0': node >=0.6.0} + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2711,6 +2756,10 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@21.1.1: + resolution: {integrity: sha512-ifJXo8zUqbQ/bLbl9sFoqHNTNWbnPY1COImFfM6CCy7z+E+jC1eY9YfOKkx0fckIg+VljAy2/87T61fp0+eEkg==} + engines: {node: '>=20'} + file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} @@ -2752,9 +2801,6 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} - formidable@3.5.2: - resolution: {integrity: sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==} - fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -2908,10 +2954,6 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hexoid@2.0.0: - resolution: {integrity: sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==} - engines: {node: '>=8'} - highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -3526,8 +3568,8 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - memoirist@0.3.0: - resolution: {integrity: sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg==} + memoirist@0.4.0: + resolution: {integrity: sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg==} meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} @@ -4465,6 +4507,9 @@ packages: resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sortablejs@1.14.0: + resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -4498,6 +4543,11 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + srvx@0.9.7: + resolution: {integrity: sha512-N2a2nx8YTq13+A8qucg4lHZREfWOVnlMHAvrA9C2jbY9/QnVEAPzjdmpFHrY6/9BxSwIbvywCj7zahuGrVzCiQ==} + engines: {node: '>=20.16.0'} + hasBin: true + ssri@9.0.1: resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -4558,6 +4608,10 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + engines: {node: '>=18'} + stylis@4.3.6: resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} @@ -4645,6 +4699,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + token-types@6.1.1: + resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} + engines: {node: '>=14.16'} + toml-eslint-parser@0.10.0: resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4714,6 +4772,10 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} @@ -4924,6 +4986,11 @@ packages: typescript: optional: true + vuedraggable@4.1.0: + resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} + peerDependencies: + vue: ^3.0.1 + watchboy@0.4.3: resolution: {integrity: sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==} engines: {node: '>=8.0.0'} @@ -4969,18 +5036,6 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -5126,6 +5181,8 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@borewit/text-codec@0.1.1': {} + '@braintree/sanitize-url@7.1.1': {} '@chevrotain/cst-dts-gen@11.0.3': @@ -5300,7 +5357,7 @@ snapshots: '@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2': dependencies: env-paths: 2.2.1 - exponential-backoff: 3.1.2 + exponential-backoff: 3.1.3 glob: 8.1.0 graceful-fs: 4.2.11 make-fetch-happen: 10.2.1 @@ -5384,21 +5441,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@elysiajs/cors@1.2.0(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3))': + '@elysiajs/cors@1.2.0(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3))': dependencies: - elysia: 1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3) + elysia: 1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3) - '@elysiajs/node@1.2.5(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3))(formidable@3.5.2)(ws@8.18.1)': + '@elysiajs/node@1.4.2(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3))': dependencies: - elysia: 1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3) - formidable: 3.5.2 - ws: 8.18.1 + crossws: 0.4.1(srvx@0.9.7) + elysia: 1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3) + srvx: 0.9.7 - '@elysiajs/swagger@1.2.2(elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3))': + '@elysiajs/swagger@1.3.1(elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3))': dependencies: '@scalar/themes': 0.9.68 '@scalar/types': 0.0.12 - elysia: 1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3) + elysia: 1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3) openapi-types: 12.1.3 pathe: 1.1.2 @@ -5554,6 +5611,8 @@ snapshots: '@eslint/core': 0.10.0 levn: 0.4.1 + '@faker-js/faker@10.1.0': {} + '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 @@ -5809,7 +5868,7 @@ snapshots: '@scalar/openapi-types': 0.1.8 '@unhead/schema': 1.11.19 - '@sinclair/typebox@0.34.27': {} + '@sinclair/typebox@0.34.41': {} '@sindresorhus/is@4.6.0': {} @@ -5910,6 +5969,15 @@ snapshots: '@tanstack/virtual-core': 3.13.2 vue: 3.5.13(typescript@5.7.3) + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.1 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + '@tootallnate/once@2.0.0': {} '@types/better-sqlite3@7.6.12': @@ -6529,8 +6597,6 @@ snapshots: array-ify@1.0.0: {} - asap@2.0.6: {} - assert-plus@1.0.0: optional: true @@ -7010,6 +7076,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.4.1(srvx@0.9.7): + optionalDependencies: + srvx: 0.9.7 + crypto-js@4.2.0: {} css-select@5.1.0: @@ -7230,6 +7300,10 @@ snapshots: optionalDependencies: supports-color: 5.5.0 + debug@4.4.3: + dependencies: + ms: 2.1.3 + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -7289,11 +7363,6 @@ snapshots: dependencies: dequal: 2.0.3 - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - dir-compare@4.2.0: dependencies: minimatch: 3.1.2 @@ -7436,13 +7505,16 @@ snapshots: runtime-required: 1.1.0 watchboy: 0.4.3 - elysia@1.2.15(@sinclair/typebox@0.34.27)(openapi-types@12.1.3)(typescript@5.7.3): + elysia@1.4.16(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.7.3): dependencies: - '@sinclair/typebox': 0.34.27 + '@sinclair/typebox': 0.34.41 cookie: 1.0.2 - memoirist: 0.3.0 - optionalDependencies: + exact-mirror: 0.2.5(@sinclair/typebox@0.34.41) + fast-decode-uri-component: 1.0.1 + file-type: 21.1.1 + memoirist: 0.4.0 openapi-types: 12.1.3 + optionalDependencies: typescript: 5.7.3 emoji-regex@10.4.0: {} @@ -7822,6 +7894,10 @@ snapshots: eventemitter3@5.0.1: {} + exact-mirror@0.2.5(@sinclair/typebox@0.34.41): + optionalDependencies: + '@sinclair/typebox': 0.34.41 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -7838,6 +7914,8 @@ snapshots: exponential-backoff@3.1.2: {} + exponential-backoff@3.1.3: {} + extract-zip@2.0.1: dependencies: debug: 4.4.0(supports-color@5.5.0) @@ -7851,6 +7929,8 @@ snapshots: extsprintf@1.4.1: optional: true + fast-decode-uri-component@1.0.1: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -7885,6 +7965,15 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-type@21.1.1: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.3.4 + token-types: 6.1.1 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + file-uri-to-path@1.0.0: {} filelist@1.0.4: @@ -7933,12 +8022,6 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - formidable@3.5.2: - dependencies: - dezalgo: 1.0.4 - hexoid: 2.0.0 - once: 1.4.0 - fraction.js@4.3.7: {} fs-constants@1.0.0: {} @@ -8123,8 +8206,6 @@ snapshots: dependencies: function-bind: 1.1.2 - hexoid@2.0.0: {} - highlight.js@11.11.1: {} hookable@5.5.3: {} @@ -8782,7 +8863,7 @@ snapshots: mdurl@2.0.0: {} - memoirist@0.3.0: {} + memoirist@0.4.0: {} meow@12.1.1: {} @@ -9795,6 +9876,8 @@ snapshots: ip-address: 9.0.5 smart-buffer: 4.2.0 + sortablejs@1.14.0: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -9827,6 +9910,8 @@ snapshots: sprintf-js@1.1.3: {} + srvx@0.9.7: {} + ssri@9.0.1: dependencies: minipass: 3.3.6 @@ -9885,6 +9970,10 @@ snapshots: dependencies: js-tokens: 9.0.1 + strtok3@10.3.4: + dependencies: + '@tokenizer/token': 0.3.0 + stylis@4.3.6: {} sumchecker@3.0.1: @@ -9979,6 +10068,12 @@ snapshots: dependencies: is-number: 7.0.0 + token-types@6.1.1: + dependencies: + '@borewit/text-codec': 0.1.1 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + toml-eslint-parser@0.10.0: dependencies: eslint-visitor-keys: 3.4.3 @@ -10026,6 +10121,8 @@ snapshots: ufo@1.5.4: {} + uint8array-extras@1.5.0: {} + undefsafe@2.0.5: {} undici-types@6.19.8: {} @@ -10222,6 +10319,11 @@ snapshots: optionalDependencies: typescript: 5.7.3 + vuedraggable@4.1.0(vue@3.5.13(typescript@5.7.3)): + dependencies: + sortablejs: 1.14.0 + vue: 3.5.13(typescript@5.7.3) + watchboy@0.4.3: dependencies: lodash.difference: 4.5.0 @@ -10271,8 +10373,6 @@ snapshots: wrappy@1.0.2: {} - ws@8.18.1: {} - xml-name-validator@4.0.0: {} xmlbuilder@15.1.1: {} diff --git a/src/main/api/index.ts b/src/main/api/index.ts index 5dc7fff5..4808620a 100644 --- a/src/main/api/index.ts +++ b/src/main/api/index.ts @@ -1,14 +1,18 @@ import { cors } from '@elysiajs/cors' -import { node } from '@elysiajs/node' import { swagger } from '@elysiajs/swagger' import { app as electronApp } from 'electron' import { Elysia } from 'elysia' import { store } from '../store' +import { importEsm } from '../utils' import folders from './routes/folders' import snippets from './routes/snippets' import tags from './routes/tags' -export function initApi() { +export async function initApi() { + // поскольку @elysiajs/node использует crossws, который работает только в ESM среде, + // то делаем хак с динамическим импортом + const { node } = await importEsm('@elysiajs/node') + const app = new Elysia({ adapter: node() }) const port = store.preferences.get('apiPort') diff --git a/src/main/api/routes/folders.ts b/src/main/api/routes/folders.ts index 5641d115..3364166e 100644 --- a/src/main/api/routes/folders.ts +++ b/src/main/api/routes/folders.ts @@ -42,7 +42,7 @@ app // Получение папок в виде древовидной структуры .get( '/tree', - () => { + (): any => { const db = useDB() const allFolders = db .prepare( @@ -141,7 +141,7 @@ app // Обновление папки .patch( '/:id', - ({ params, body, error }) => { + ({ params, body, status }) => { const db = useDB() const { id } = params const now = Date.now() @@ -187,7 +187,7 @@ app } if (updateFields.length === 0) { - return error(400, { message: 'Need at least one field to update' }) + return status(400, { message: 'Need at least one field to update' }) } updateFields.push('updatedAt = ?') @@ -204,7 +204,7 @@ app | undefined if (!folder) { - return error(404, { message: 'Folder not found' }) + return status(404, { message: 'Folder not found' }) } // Обновляем порядок, только если изменился родитель или индекс @@ -301,7 +301,7 @@ app // Удаление папки .delete( '/:id', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const { id } = params @@ -314,7 +314,7 @@ app .get(id) if (!folder) { - return error(404, { message: 'Folder not found' }) + return status(404, { message: 'Folder not found' }) } const transaction = db.transaction(() => { diff --git a/src/main/api/routes/snippets.ts b/src/main/api/routes/snippets.ts index a8888d8f..edfe72af 100644 --- a/src/main/api/routes/snippets.ts +++ b/src/main/api/routes/snippets.ts @@ -231,7 +231,7 @@ app // Обновление сниппета .patch( '/:id', - ({ params, body, error }) => { + ({ params, body, status }) => { const db = useDB() const { id } = params @@ -264,7 +264,7 @@ app } if (updateFields.length === 0) { - return error(400, { message: 'Need at least one field to update' }) + return status(400, { message: 'Need at least one field to update' }) } updateFields.push('updatedAt = ?') @@ -283,7 +283,7 @@ app const result = stmt.run(...updateParams) if (!result.changes) { - return error(404, { message: 'Snippet not found' }) + return status(404, { message: 'Snippet not found' }) } return { message: 'Snippet updated' } @@ -298,7 +298,7 @@ app // Обновление содержимого сниппета .patch( '/:id/contents/:contentId', - ({ params, body, error }) => { + ({ params, body, status }) => { const db = useDB() const { id, contentId } = params @@ -321,7 +321,7 @@ app } if (updateFields.length === 0) { - return error(400, { message: 'Need at least one field to update' }) + return status(400, { message: 'Need at least one field to update' }) } updateParams.push(contentId) @@ -335,7 +335,7 @@ app const contentsResult = contentsStmt.run(...updateParams) if (!contentsResult.changes) { - return error(404, { message: 'Snippet content not found' }) + return status(404, { message: 'Snippet content not found' }) } // Обновляем дату сниппета только если были реальные изменения в данных @@ -348,7 +348,7 @@ app const snippetResult = snippetsStmt.run(now, id) if (!snippetResult.changes) { - return error(404, { message: 'Snippet not found' }) + return status(404, { message: 'Snippet not found' }) } } @@ -364,7 +364,7 @@ app // Добавление тега к сниппету .post( '/:id/tags/:tagId', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const { id, tagId } = params @@ -378,7 +378,7 @@ app .get(id) if (!snippet) { - return error(404, { message: 'Snippet not found' }) + return status(404, { message: 'Snippet not found' }) } // Проверяем, существует ли тег @@ -391,7 +391,7 @@ app .get(tagId) if (!tag) { - return error(404, { message: 'Tag not found' }) + return status(404, { message: 'Tag not found' }) } // Добавляем связь между сниппетом и тегом @@ -415,7 +415,7 @@ app // Удаление тега из сниппета .delete( '/:id/tags/:tagId', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const { id, tagId } = params @@ -429,7 +429,7 @@ app .get(id) if (!snippet) { - return error(404, { message: 'Snippet not found' }) + return status(404, { message: 'Snippet not found' }) } // Проверяем, существует ли тег @@ -442,7 +442,7 @@ app .get(tagId) if (!tag) { - return error(404, { message: 'Tag not found' }) + return status(404, { message: 'Tag not found' }) } // Удаляем связь между сниппетом и тегом @@ -456,7 +456,7 @@ app const result = stmt.run(id, tagId) if (!result.changes) { - return error(404, { + return status(404, { message: 'Tag is not associated with this snippet', }) } @@ -472,7 +472,7 @@ app // Удаление сниппета .delete( '/:id', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const { id } = params @@ -485,7 +485,7 @@ app .get(id) if (!snippet) { - return error(404, { message: 'Snippet not found' }) + return status(404, { message: 'Snippet not found' }) } const transaction = db.transaction(() => { @@ -524,7 +524,7 @@ app // Удаление всех сниппетов в корзине .delete( '/trash', - ({ error }) => { + ({ status }) => { const db = useDB() const deletedSnippets = db .prepare( @@ -535,7 +535,7 @@ app .all() as { id: number }[] if (deletedSnippets.length === 0) { - return error(404, { message: 'No snippets in trash' }) + return status(404, { message: 'No snippets in trash' }) } const transaction = db.transaction(() => { @@ -582,7 +582,7 @@ app // Удаление содержимого сниппета .delete( '/:id/contents/:contentId', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const { contentId } = params @@ -595,7 +595,7 @@ app .run(contentId) if (!result.changes) { - return error(404, { message: 'Snippet content not found' }) + return status(404, { message: 'Snippet content not found' }) } return { message: 'Snippet content deleted' } diff --git a/src/main/api/routes/tags.ts b/src/main/api/routes/tags.ts index e327d05b..d7510a6f 100644 --- a/src/main/api/routes/tags.ts +++ b/src/main/api/routes/tags.ts @@ -49,7 +49,7 @@ app // Удаление тега и удаление его из всех сниппетов .delete( '/:id', - ({ params, error }) => { + ({ params, status }) => { const db = useDB() const tag = db .prepare( @@ -60,7 +60,7 @@ app .get(params.id) if (!tag) { - return error(404, { message: 'Tag not found' }) + return status(404, { message: 'Tag not found' }) } const transaction = db.transaction(() => { diff --git a/src/main/i18n/locales/cs_CZ/devtools.json b/src/main/i18n/locales/cs_CZ/devtools.json index 56037834..8c729360 100644 --- a/src/main/i18n/locales/cs_CZ/devtools.json +++ b/src/main/i18n/locales/cs_CZ/devtools.json @@ -1,5 +1,86 @@ { "label": "Vývojářské nástroje", + "generators": { + "label": "Generátory", + "lorem": { + "label": "Generátor Lorem Ipsum", + "description": "Generovat zástupný text", + "selectType": "Vybrat typ", + "maxCount": "Max {{count}}", + "types": { + "words": "Slova", + "sentences": "Věty", + "paragraphs": "Odstavce" + } + }, + "json": { + "label": "JSON generátor", + "description": "Generovat náhodná JSON data s různými typy polí", + "fields": "Pole", + "fieldName": "Název pole", + "selectType": "Vybrat typ", + "addField": "Přidat pole", + "rowCount": "Počet řádků", + "maxRows": "Max 1000", + "categories": { + "general": "Obecné", + "person": "Osoba", + "internet": "Internet", + "location": "Umístění", + "finance": "Finance", + "commerce": "Obchod", + "company": "Společnost", + "lorem": "Lorem", + "date": "Datum", + "number": "Číslo", + "phone": "Telefon", + "image": "Obrázek" + }, + "types": { + "rowNumber": "Číslo řádku", + "firstName": "Křestní jméno", + "lastName": "Příjmení", + "fullName": "Celé jméno", + "gender": "Pohlaví", + "jobTitle": "Pracovní pozice", + "email": "E-mailová adresa", + "username": "Uživatelské jméno", + "password": "Heslo", + "url": "URL", + "ipv4": "IP adresa v4", + "ipv6": "IP adresa v6", + "userAgent": "User Agent", + "city": "Město", + "country": "Země", + "streetAddress": "Adresa", + "zipCode": "PSČ", + "latitude": "Zeměpisná šířka", + "longitude": "Zeměpisná délka", + "amount": "Částka", + "currencyCode": "Kód měny", + "creditCardNumber": "Číslo kreditní karty", + "productName": "Název produktu", + "price": "Cena", + "department": "Oddělení", + "companyName": "Název společnosti", + "catchPhrase": "Slogan", + "word": "Slovo", + "sentence": "Věta", + "paragraph": "Odstavec", + "past": "Minulé datum", + "future": "Budoucí datum", + "recent": "Nedávné datum", + "birthdate": "Datum narození", + "int": "Celé číslo", + "float": "Desetinné číslo", + "boolean": "Boolean", + "phoneNumber": "Telefonní číslo", + "imei": "IMEI", + "avatar": "URL avatara", + "imageUrl": "URL obrázku" + } + } + }, "converters": { "label": "Převodníky", "caseConverter": { diff --git a/src/main/i18n/locales/cs_CZ/menu.json b/src/main/i18n/locales/cs_CZ/menu.json index ed766e11..233baebf 100644 --- a/src/main/i18n/locales/cs_CZ/menu.json +++ b/src/main/i18n/locales/cs_CZ/menu.json @@ -1,7 +1,7 @@ { "app": { "label": "massCode", - "preferences": "Předvolby", + "preferences": "Nastavení", "devtools": "Vývojářské nástroje", "update": "Zkontrolovat aktualizace...", "quit": "Ukončit massCode", @@ -72,5 +72,9 @@ }, "devtools": { "label": "Vývojářské nástroje" + }, + "window": { + "label": "Okno", + "minimize": "Minimalizovat" } } diff --git a/src/main/i18n/locales/cs_CZ/messages.json b/src/main/i18n/locales/cs_CZ/messages.json index fae7a135..ce8f3cc0 100644 --- a/src/main/i18n/locales/cs_CZ/messages.json +++ b/src/main/i18n/locales/cs_CZ/messages.json @@ -8,10 +8,20 @@ "migrateDb": [ "Opravdu chcete provést migraci?", "Během migrace bude současná knihovna přepsána." - ] + ], + "backup": { + "restore": "Opravdu chcete obnovit ze zálohy?", + "delete": "Opravdu chcete smazat tuto zálohu?" + } }, "success": { - "migrate": "Databáze byla úspěšně migrována." + "copied": "Zkopírováno do schránky", + "migrate": "Databáze byla úspěšně migrována.", + "backup": { + "created": "Záloha byla úspěšně vytvořena.", + "restored": "Záloha byla úspěšně obnovena.", + "deleted": "Záloha byla úspěšně smazána." + } }, "warning": { "noUndo": "Tuto akci nelze vrátit zpět.", @@ -25,7 +35,9 @@ "languages" ] }, - "error": {}, + "error": { + "backup": "Operace zálohování selhala" + }, "description": { "storage": "Pro použití synchronizačních služeb jako iCloud Drive, Google Drive nebo Dropbox jednoduše přesuňte úložiště do odpovídajících synchronizovaných složek", "migrate": { @@ -36,6 +48,10 @@ "Všechny složky budou na první úrovni, protože JSON soubor (pod v2.1) nepodporuje vnořené složky.", "Snippety s nepodporovanými jazyky budou nastaveny na výchozí Plain Text." ] + }, + "language": "Pro aplikaci změny jazyka je nutné aplikaci znovu načíst.", + "backup": { + "manual": "Manuální záloha nebude automaticky smazána, když počet záloh překročí limit." } }, "special": { diff --git a/src/main/i18n/locales/cs_CZ/preferences.json b/src/main/i18n/locales/cs_CZ/preferences.json index 5dc8fe9b..ba7137d2 100644 --- a/src/main/i18n/locales/cs_CZ/preferences.json +++ b/src/main/i18n/locales/cs_CZ/preferences.json @@ -1,10 +1,31 @@ { "label": "Předvolby", "storage": { + "section": { + "main": "Hlavní", + "backup": "Záloha" + }, "label": "Úložiště", "migrate": "Migrovat", "count": "Počet", - "clearDatabase": "Vymazat databázi" + "clearDatabase": "Vymazat databázi", + "backup": { + "label": "Záloha", + "enabled": "Automatická záloha", + "interval": { + "label": "Interval", + "1": "Každou hodinu", + "6": "Každých 6 hodin", + "12": "Každých 12 hodin", + "24": "Každých 24 hodin" + }, + "maxBackups": "Maximální počet záloh", + "createNow": "Vytvořit zálohu nyní", + "restore": "Obnovit ze zálohy", + "list": "Seznam záloh", + "lastBackup": "Poslední záloha", + "noBackups": "Nebyly nalezeny žádné zálohy" + } }, "editor": { "label": "Editor", @@ -37,7 +58,8 @@ "theme": { "label": "Motiv", "light": "Světlý", - "dark": "Tmavý" + "dark": "Tmavý", + "system": "Systémový" } }, "language": { @@ -45,7 +67,7 @@ }, "markdown": { "label": "Markdown", - "codeRenderer": "Renderer kódových bloků" + "codeRenderer": "Renderer bloků kódu" }, "api": { "label": "API Port", diff --git a/src/main/i18n/locales/cs_CZ/ui.json b/src/main/i18n/locales/cs_CZ/ui.json index 9192d008..f894df06 100644 --- a/src/main/i18n/locales/cs_CZ/ui.json +++ b/src/main/i18n/locales/cs_CZ/ui.json @@ -63,7 +63,8 @@ "fromFavorites": "Odebrat z oblíbených" }, "reload": { - "storage": "Znovu načíst úložiště" + "storage": "Znovu načíst úložiště", + "app": "Znovu načíst aplikaci" }, "delete": { "common": "Smazat", @@ -80,6 +81,11 @@ }, "copy": { "snippetLink": "Kopírovat odkaz na snippet" + }, + "backup": { + "create": "Vytvořit zálohu", + "restore": "Obnovit ze zálohy", + "delete": "Smazat zálohu" } }, "sidebar": { diff --git a/src/main/i18n/locales/de_DE/devtools.json b/src/main/i18n/locales/de_DE/devtools.json index 70aa3d3e..1195212e 100644 --- a/src/main/i18n/locales/de_DE/devtools.json +++ b/src/main/i18n/locales/de_DE/devtools.json @@ -1,5 +1,86 @@ { "label": "Entwicklertools", + "generators": { + "label": "Generatoren", + "lorem": { + "label": "Lorem Ipsum Generator", + "description": "Platzhalter-Text generieren", + "selectType": "Typ auswählen", + "maxCount": "Max {{count}}", + "types": { + "words": "Wörter", + "sentences": "Sätze", + "paragraphs": "Absätze" + } + }, + "json": { + "label": "JSON Generator", + "description": "Zufällige JSON-Daten mit verschiedenen Feldtypen generieren", + "fields": "Felder", + "fieldName": "Feldname", + "selectType": "Typ auswählen", + "addField": "Feld hinzufügen", + "rowCount": "Anzahl der Zeilen", + "maxRows": "Max 1000", + "categories": { + "general": "Allgemein", + "person": "Person", + "internet": "Internet", + "location": "Standort", + "finance": "Finanzen", + "commerce": "Handel", + "company": "Unternehmen", + "lorem": "Lorem", + "date": "Datum", + "number": "Zahl", + "phone": "Telefon", + "image": "Bild" + }, + "types": { + "rowNumber": "Zeilennummer", + "firstName": "Vorname", + "lastName": "Nachname", + "fullName": "Vollständiger Name", + "gender": "Geschlecht", + "jobTitle": "Berufsbezeichnung", + "email": "E-Mail-Adresse", + "username": "Benutzername", + "password": "Passwort", + "url": "URL", + "ipv4": "IP-Adresse v4", + "ipv6": "IP-Adresse v6", + "userAgent": "User Agent", + "city": "Stadt", + "country": "Land", + "streetAddress": "Straßenadresse", + "zipCode": "Postleitzahl", + "latitude": "Breitengrad", + "longitude": "Längengrad", + "amount": "Betrag", + "currencyCode": "Währungscode", + "creditCardNumber": "Kreditkartennummer", + "productName": "Produktname", + "price": "Preis", + "department": "Abteilung", + "companyName": "Firmenname", + "catchPhrase": "Slogan", + "word": "Wort", + "sentence": "Satz", + "paragraph": "Absatz", + "past": "Vergangenes Datum", + "future": "Zukünftiges Datum", + "recent": "Kürzliches Datum", + "birthdate": "Geburtsdatum", + "int": "Ganzzahl", + "float": "Gleitkommazahl", + "boolean": "Boolesch", + "phoneNumber": "Telefonnummer", + "imei": "IMEI", + "avatar": "Avatar-URL", + "imageUrl": "Bild-URL" + } + } + }, "converters": { "label": "Konverter", "caseConverter": { diff --git a/src/main/i18n/locales/de_DE/messages.json b/src/main/i18n/locales/de_DE/messages.json index 01eba0c1..fbd3b4eb 100644 --- a/src/main/i18n/locales/de_DE/messages.json +++ b/src/main/i18n/locales/de_DE/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Datenbank erfolgreich migriert." + "copied": "In die Zwischenablage kopiert", + "migrate": "Datenbank erfolgreich migriert.", + "backup": { + "created": "Sicherung erfolgreich erstellt.", + "restored": "Sicherung erfolgreich wiederhergestellt.", + "deleted": "Sicherung erfolgreich gelöscht." + } }, "warning": { "noUndo": "Diese Aktion kann nicht rückgängig gemacht werden.", diff --git a/src/main/i18n/locales/el_GR/devtools.json b/src/main/i18n/locales/el_GR/devtools.json index 0b5cf062..3fed0784 100644 --- a/src/main/i18n/locales/el_GR/devtools.json +++ b/src/main/i18n/locales/el_GR/devtools.json @@ -1,5 +1,86 @@ { "label": "Εργαλεία Προγραμματιστή", + "generators": { + "label": "Γεννήτριες", + "lorem": { + "label": "Γεννήτρια Lorem Ipsum", + "description": "Δημιουργία κειμένου κράτησης θέσης", + "selectType": "Επιλέξτε τύπο", + "maxCount": "Μέγιστο {{count}}", + "types": { + "words": "Λέξεις", + "sentences": "Προτάσεις", + "paragraphs": "Παράγραφοι" + } + }, + "json": { + "label": "Γεννήτρια JSON", + "description": "Δημιουργία τυχαίων δεδομένων JSON με διάφορους τύπους πεδίων", + "fields": "Πεδία", + "fieldName": "Όνομα πεδίου", + "selectType": "Επιλέξτε τύπο", + "addField": "Προσθήκη πεδίου", + "rowCount": "Αριθμός γραμμών", + "maxRows": "Μέγιστο 1000", + "categories": { + "general": "Γενικά", + "person": "Άτομο", + "internet": "Διαδίκτυο", + "location": "Τοποθεσία", + "finance": "Οικονομικά", + "commerce": "Εμπόριο", + "company": "Εταιρεία", + "lorem": "Lorem", + "date": "Ημερομηνία", + "number": "Αριθμός", + "phone": "Τηλέφωνο", + "image": "Εικόνα" + }, + "types": { + "rowNumber": "Αριθμός γραμμής", + "firstName": "Όνομα", + "lastName": "Επώνυμο", + "fullName": "Πλήρες όνομα", + "gender": "Φύλο", + "jobTitle": "Τίτλος εργασίας", + "email": "Διεύθυνση email", + "username": "Όνομα χρήστη", + "password": "Κωδικός πρόσβασης", + "url": "URL", + "ipv4": "Διεύθυνση IP v4", + "ipv6": "Διεύθυνση IP v6", + "userAgent": "User Agent", + "city": "Πόλη", + "country": "Χώρα", + "streetAddress": "Διεύθυνση", + "zipCode": "Ταχυδρομικός κώδικας", + "latitude": "Γεωγραφικό πλάτος", + "longitude": "Γεωγραφικό μήκος", + "amount": "Ποσό", + "currencyCode": "Κωδικός νομίσματος", + "creditCardNumber": "Αριθμός πιστωτικής κάρτας", + "productName": "Όνομα προϊόντος", + "price": "Τιμή", + "department": "Τμήμα", + "companyName": "Όνομα εταιρείας", + "catchPhrase": "Σλόγκαν", + "word": "Λέξη", + "sentence": "Πρόταση", + "paragraph": "Παράγραφος", + "past": "Προηγούμενη ημερομηνία", + "future": "Μελλοντική ημερομηνία", + "recent": "Πρόσφατη ημερομηνία", + "birthdate": "Ημερομηνία γέννησης", + "int": "Ακέραιος", + "float": "Δεκαδικός", + "boolean": "Boolean", + "phoneNumber": "Αριθμός τηλεφώνου", + "imei": "IMEI", + "avatar": "URL avatar", + "imageUrl": "URL εικόνας" + } + } + }, "converters": { "label": "Μετατροπείς", "caseConverter": { diff --git a/src/main/i18n/locales/el_GR/messages.json b/src/main/i18n/locales/el_GR/messages.json index a224d699..2efa8bf7 100644 --- a/src/main/i18n/locales/el_GR/messages.json +++ b/src/main/i18n/locales/el_GR/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Η DB μετέφερε επιτυχώς τα δεδομένα." + "copied": "Αντιγράφηκε στο πρόχειρο", + "migrate": "Η DB μετέφερε επιτυχώς τα δεδομένα.", + "backup": { + "created": "Το αντίγραφο ασφαλείας δημιουργήθηκε επιτυχώς.", + "restored": "Το αντίγραφο ασφαλείας αποκαταστάθηκε επιτυχώς.", + "deleted": "Το αντίγραφο ασφαλείας διαγράφηκε επιτυχώς." + } }, "warning": { "noUndo": "Δεν μπορείτε να αναιρέσετε αυτήν την ενέργεια.", diff --git a/src/main/i18n/locales/en_US/devtools.json b/src/main/i18n/locales/en_US/devtools.json index cf3ef682..60972402 100644 --- a/src/main/i18n/locales/en_US/devtools.json +++ b/src/main/i18n/locales/en_US/devtools.json @@ -1,5 +1,86 @@ { "label": "Developer Tools", + "generators": { + "label": "Generators", + "lorem": { + "label": "Lorem Ipsum Generator", + "description": "Generate placeholder text", + "selectType": "Select type", + "maxCount": "Max {{count}}", + "types": { + "words": "Words", + "sentences": "Sentences", + "paragraphs": "Paragraphs" + } + }, + "json": { + "label": "JSON Generator", + "description": "Generate random JSON data with various field types", + "fields": "Fields", + "fieldName": "Field name", + "selectType": "Select type", + "addField": "Add Field", + "rowCount": "Number of Rows", + "maxRows": "Max 1000", + "categories": { + "general": "General", + "person": "Person", + "internet": "Internet", + "location": "Location", + "finance": "Finance", + "commerce": "Commerce", + "company": "Company", + "lorem": "Lorem", + "date": "Date", + "number": "Number", + "phone": "Phone", + "image": "Image" + }, + "types": { + "rowNumber": "Row Number", + "firstName": "First Name", + "lastName": "Last Name", + "fullName": "Full Name", + "gender": "Gender", + "jobTitle": "Job Title", + "email": "Email Address", + "username": "Username", + "password": "Password", + "url": "URL", + "ipv4": "IP Address v4", + "ipv6": "IP Address v6", + "userAgent": "User Agent", + "city": "City", + "country": "Country", + "streetAddress": "Street Address", + "zipCode": "Zip Code", + "latitude": "Latitude", + "longitude": "Longitude", + "amount": "Amount", + "currencyCode": "Currency Code", + "creditCardNumber": "Credit Card Number", + "productName": "Product Name", + "price": "Price", + "department": "Department", + "companyName": "Company Name", + "catchPhrase": "Catch Phrase", + "word": "Word", + "sentence": "Sentence", + "paragraph": "Paragraph", + "past": "Past Date", + "future": "Future Date", + "recent": "Recent Date", + "birthdate": "Birthdate", + "int": "Integer", + "float": "Float", + "boolean": "Boolean", + "phoneNumber": "Phone Number", + "imei": "IMEI", + "avatar": "Avatar URL", + "imageUrl": "Image URL" + } + } + }, "converters": { "label": "Converters", "caseConverter": { diff --git a/src/main/i18n/locales/en_US/messages.json b/src/main/i18n/locales/en_US/messages.json index edae0dc2..81479a45 100644 --- a/src/main/i18n/locales/en_US/messages.json +++ b/src/main/i18n/locales/en_US/messages.json @@ -15,6 +15,7 @@ } }, "success": { + "copied": "Copied to clipboard", "migrate": "DB successfully migrated.", "backup": { "created": "Backup successfully created.", diff --git a/src/main/i18n/locales/es_ES/devtools.json b/src/main/i18n/locales/es_ES/devtools.json index cf4ad0f3..4337cf12 100644 --- a/src/main/i18n/locales/es_ES/devtools.json +++ b/src/main/i18n/locales/es_ES/devtools.json @@ -1,5 +1,86 @@ { "label": "Herramientas de desarrollo", + "generators": { + "label": "Generadores", + "lorem": { + "label": "Generador Lorem Ipsum", + "description": "Generar texto de marcador de posición", + "selectType": "Seleccionar tipo", + "maxCount": "Máx {{count}}", + "types": { + "words": "Palabras", + "sentences": "Oraciones", + "paragraphs": "Párrafos" + } + }, + "json": { + "label": "Generador JSON", + "description": "Generar datos JSON aleatorios con varios tipos de campos", + "fields": "Campos", + "fieldName": "Nombre del campo", + "selectType": "Seleccionar tipo", + "addField": "Agregar campo", + "rowCount": "Número de filas", + "maxRows": "Máx 1000", + "categories": { + "general": "General", + "person": "Persona", + "internet": "Internet", + "location": "Ubicación", + "finance": "Finanzas", + "commerce": "Comercio", + "company": "Empresa", + "lorem": "Lorem", + "date": "Fecha", + "number": "Número", + "phone": "Teléfono", + "image": "Imagen" + }, + "types": { + "rowNumber": "Número de fila", + "firstName": "Nombre", + "lastName": "Apellido", + "fullName": "Nombre completo", + "gender": "Género", + "jobTitle": "Título del trabajo", + "email": "Dirección de correo electrónico", + "username": "Nombre de usuario", + "password": "Contraseña", + "url": "URL", + "ipv4": "Dirección IP v4", + "ipv6": "Dirección IP v6", + "userAgent": "User Agent", + "city": "Ciudad", + "country": "País", + "streetAddress": "Dirección", + "zipCode": "Código postal", + "latitude": "Latitud", + "longitude": "Longitud", + "amount": "Cantidad", + "currencyCode": "Código de moneda", + "creditCardNumber": "Número de tarjeta de crédito", + "productName": "Nombre del producto", + "price": "Precio", + "department": "Departamento", + "companyName": "Nombre de la empresa", + "catchPhrase": "Eslogan", + "word": "Palabra", + "sentence": "Oración", + "paragraph": "Párrafo", + "past": "Fecha pasada", + "future": "Fecha futura", + "recent": "Fecha reciente", + "birthdate": "Fecha de nacimiento", + "int": "Entero", + "float": "Flotante", + "boolean": "Booleano", + "phoneNumber": "Número de teléfono", + "imei": "IMEI", + "avatar": "URL del avatar", + "imageUrl": "URL de la imagen" + } + } + }, "converters": { "label": "Convertidores", "caseConverter": { diff --git a/src/main/i18n/locales/es_ES/messages.json b/src/main/i18n/locales/es_ES/messages.json index ff92bb0c..daacf122 100644 --- a/src/main/i18n/locales/es_ES/messages.json +++ b/src/main/i18n/locales/es_ES/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Base de datos migrada exitosamente." + "copied": "Copiado al portapapeles", + "migrate": "Base de datos migrada exitosamente.", + "backup": { + "created": "Copia de seguridad creada exitosamente.", + "restored": "Copia de seguridad restaurada exitosamente.", + "deleted": "Copia de seguridad eliminada exitosamente." + } }, "warning": { "noUndo": "No podrás deshacer esta acción.", diff --git a/src/main/i18n/locales/fa_IR/devtools.json b/src/main/i18n/locales/fa_IR/devtools.json index ca30fcfa..adaa066f 100644 --- a/src/main/i18n/locales/fa_IR/devtools.json +++ b/src/main/i18n/locales/fa_IR/devtools.json @@ -1,5 +1,86 @@ { "label": "ابزارهای توسعه‌دهنده", + "generators": { + "label": "تولیدکننده‌ها", + "lorem": { + "label": "تولیدکننده Lorem Ipsum", + "description": "تولید متن نگهدارنده", + "selectType": "نوع را انتخاب کنید", + "maxCount": "حداکثر {{count}}", + "types": { + "words": "کلمات", + "sentences": "جمله‌ها", + "paragraphs": "پاراگراف‌ها" + } + }, + "json": { + "label": "تولیدکننده JSON", + "description": "تولید داده‌های JSON تصادفی با انواع مختلف فیلد", + "fields": "فیلدها", + "fieldName": "نام فیلد", + "selectType": "انتخاب نوع", + "addField": "افزودن فیلد", + "rowCount": "تعداد ردیف‌ها", + "maxRows": "حداکثر ۱۰۰۰", + "categories": { + "general": "عمومی", + "person": "شخص", + "internet": "اینترنت", + "location": "مکان", + "finance": "مالی", + "commerce": "تجارت", + "company": "شرکت", + "lorem": "Lorem", + "date": "تاریخ", + "number": "عدد", + "phone": "تلفن", + "image": "تصویر" + }, + "types": { + "rowNumber": "شماره ردیف", + "firstName": "نام", + "lastName": "نام خانوادگی", + "fullName": "نام کامل", + "gender": "جنسیت", + "jobTitle": "عنوان شغلی", + "email": "آدرس ایمیل", + "username": "نام کاربری", + "password": "رمز عبور", + "url": "URL", + "ipv4": "آدرس IP v4", + "ipv6": "آدرس IP v6", + "userAgent": "User Agent", + "city": "شهر", + "country": "کشور", + "streetAddress": "آدرس خیابان", + "zipCode": "کد پستی", + "latitude": "عرض جغرافیایی", + "longitude": "طول جغرافیایی", + "amount": "مقدار", + "currencyCode": "کد ارز", + "creditCardNumber": "شماره کارت اعتباری", + "productName": "نام محصول", + "price": "قیمت", + "department": "بخش", + "companyName": "نام شرکت", + "catchPhrase": "شعار", + "word": "کلمه", + "sentence": "جمله", + "paragraph": "پاراگراف", + "past": "تاریخ گذشته", + "future": "تاریخ آینده", + "recent": "تاریخ اخیر", + "birthdate": "تاریخ تولد", + "int": "عدد صحیح", + "float": "عدد اعشاری", + "boolean": "بولی", + "phoneNumber": "شماره تلفن", + "imei": "IMEI", + "avatar": "URL آواتار", + "imageUrl": "URL تصویر" + } + } + }, "converters": { "label": "مبدل‌ها", "caseConverter": { diff --git a/src/main/i18n/locales/fa_IR/messages.json b/src/main/i18n/locales/fa_IR/messages.json index 982fb11d..d10eddca 100644 --- a/src/main/i18n/locales/fa_IR/messages.json +++ b/src/main/i18n/locales/fa_IR/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "پایگاه داده با موفقیت مهاجرت کرد." + "copied": "در کلیپ‌بورد کپی شد", + "migrate": "پایگاه داده با موفقیت مهاجرت کرد.", + "backup": { + "created": "پشتیبان با موفقیت ایجاد شد.", + "restored": "پشتیبان با موفقیت بازیابی شد.", + "deleted": "پشتیبان با موفقیت حذف شد." + } }, "warning": { "noUndo": "شما نمی‌توانید این عمل را برگردانید.", diff --git a/src/main/i18n/locales/fr_FR/devtools.json b/src/main/i18n/locales/fr_FR/devtools.json index c4880316..aba6fbe3 100644 --- a/src/main/i18n/locales/fr_FR/devtools.json +++ b/src/main/i18n/locales/fr_FR/devtools.json @@ -1,5 +1,86 @@ { "label": "Outils de développement", + "generators": { + "label": "Générateurs", + "lorem": { + "label": "Générateur Lorem Ipsum", + "description": "Générer du texte d'espace réservé", + "selectType": "Sélectionner le type", + "maxCount": "Max {{count}}", + "types": { + "words": "Mots", + "sentences": "Phrases", + "paragraphs": "Paragraphes" + } + }, + "json": { + "label": "Générateur JSON", + "description": "Générer des données JSON aléatoires avec différents types de champs", + "fields": "Champs", + "fieldName": "Nom du champ", + "selectType": "Sélectionner le type", + "addField": "Ajouter un champ", + "rowCount": "Nombre de lignes", + "maxRows": "Max 1000", + "categories": { + "general": "Général", + "person": "Personne", + "internet": "Internet", + "location": "Localisation", + "finance": "Finance", + "commerce": "Commerce", + "company": "Entreprise", + "lorem": "Lorem", + "date": "Date", + "number": "Nombre", + "phone": "Téléphone", + "image": "Image" + }, + "types": { + "rowNumber": "Numéro de ligne", + "firstName": "Prénom", + "lastName": "Nom de famille", + "fullName": "Nom complet", + "gender": "Genre", + "jobTitle": "Titre du poste", + "email": "Adresse e-mail", + "username": "Nom d'utilisateur", + "password": "Mot de passe", + "url": "URL", + "ipv4": "Adresse IP v4", + "ipv6": "Adresse IP v6", + "userAgent": "User Agent", + "city": "Ville", + "country": "Pays", + "streetAddress": "Adresse", + "zipCode": "Code postal", + "latitude": "Latitude", + "longitude": "Longitude", + "amount": "Montant", + "currencyCode": "Code de devise", + "creditCardNumber": "Numéro de carte de crédit", + "productName": "Nom du produit", + "price": "Prix", + "department": "Département", + "companyName": "Nom de l'entreprise", + "catchPhrase": "Slogan", + "word": "Mot", + "sentence": "Phrase", + "paragraph": "Paragraphe", + "past": "Date passée", + "future": "Date future", + "recent": "Date récente", + "birthdate": "Date de naissance", + "int": "Entier", + "float": "Flottant", + "boolean": "Booléen", + "phoneNumber": "Numéro de téléphone", + "imei": "IMEI", + "avatar": "URL de l'avatar", + "imageUrl": "URL de l'image" + } + } + }, "converters": { "label": "Convertisseurs", "caseConverter": { diff --git a/src/main/i18n/locales/fr_FR/messages.json b/src/main/i18n/locales/fr_FR/messages.json index 43f08d48..d95d657a 100644 --- a/src/main/i18n/locales/fr_FR/messages.json +++ b/src/main/i18n/locales/fr_FR/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Base de données migrée avec succès." + "copied": "Copié dans le presse-papiers", + "migrate": "Base de données migrée avec succès.", + "backup": { + "created": "Sauvegarde créée avec succès.", + "restored": "Sauvegarde restaurée avec succès.", + "deleted": "Sauvegarde supprimée avec succès." + } }, "warning": { "noUndo": "Vous ne pouvez pas annuler cette action.", diff --git a/src/main/i18n/locales/ja_JP/devtools.json b/src/main/i18n/locales/ja_JP/devtools.json index 1cf01b36..cd6e0141 100644 --- a/src/main/i18n/locales/ja_JP/devtools.json +++ b/src/main/i18n/locales/ja_JP/devtools.json @@ -1,5 +1,86 @@ { "label": "開発者ツール", + "generators": { + "label": "ジェネレーター", + "lorem": { + "label": "Lorem Ipsum ジェネレーター", + "description": "プレースホルダーテキストを生成", + "selectType": "タイプを選択", + "maxCount": "最大 {{count}}", + "types": { + "words": "単語", + "sentences": "文", + "paragraphs": "段落" + } + }, + "json": { + "label": "JSON ジェネレーター", + "description": "さまざまなフィールドタイプでランダムな JSON データを生成", + "fields": "フィールド", + "fieldName": "フィールド名", + "selectType": "タイプを選択", + "addField": "フィールドを追加", + "rowCount": "行数", + "maxRows": "最大 1000", + "categories": { + "general": "一般", + "person": "人物", + "internet": "インターネット", + "location": "場所", + "finance": "財務", + "commerce": "商取引", + "company": "会社", + "lorem": "Lorem", + "date": "日付", + "number": "数字", + "phone": "電話", + "image": "画像" + }, + "types": { + "rowNumber": "行番号", + "firstName": "名", + "lastName": "姓", + "fullName": "フルネーム", + "gender": "性別", + "jobTitle": "職種", + "email": "メールアドレス", + "username": "ユーザー名", + "password": "パスワード", + "url": "URL", + "ipv4": "IP アドレス v4", + "ipv6": "IP アドレス v6", + "userAgent": "User Agent", + "city": "都市", + "country": "国", + "streetAddress": "住所", + "zipCode": "郵便番号", + "latitude": "緯度", + "longitude": "経度", + "amount": "金額", + "currencyCode": "通貨コード", + "creditCardNumber": "クレジットカード番号", + "productName": "製品名", + "price": "価格", + "department": "部門", + "companyName": "会社名", + "catchPhrase": "キャッチフレーズ", + "word": "単語", + "sentence": "文", + "paragraph": "段落", + "past": "過去の日付", + "future": "未来の日付", + "recent": "最近の日付", + "birthdate": "生年月日", + "int": "整数", + "float": "浮動小数点", + "boolean": "ブール値", + "phoneNumber": "電話番号", + "imei": "IMEI", + "avatar": "アバター URL", + "imageUrl": "画像 URL" + } + } + }, "converters": { "label": "コンバーター", "caseConverter": { diff --git a/src/main/i18n/locales/ja_JP/messages.json b/src/main/i18n/locales/ja_JP/messages.json index 304767e5..a68bd932 100644 --- a/src/main/i18n/locales/ja_JP/messages.json +++ b/src/main/i18n/locales/ja_JP/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "データベースの移行が完了しました。" + "copied": "クリップボードにコピーしました", + "migrate": "データベースの移行が完了しました。", + "backup": { + "created": "バックアップが正常に作成されました。", + "restored": "バックアップが正常に復元されました。", + "deleted": "バックアップが正常に削除されました。" + } }, "warning": { "noUndo": "この操作は取り消せません。", diff --git a/src/main/i18n/locales/pl_PL/devtools.json b/src/main/i18n/locales/pl_PL/devtools.json index 73daf368..79509561 100644 --- a/src/main/i18n/locales/pl_PL/devtools.json +++ b/src/main/i18n/locales/pl_PL/devtools.json @@ -1,5 +1,86 @@ { "label": "Narzędzia deweloperskie", + "generators": { + "label": "Generatory", + "lorem": { + "label": "Generator Lorem Ipsum", + "description": "Generuj tekst zastępczy", + "selectType": "Wybierz typ", + "maxCount": "Maks {{count}}", + "types": { + "words": "Słowa", + "sentences": "Zdania", + "paragraphs": "Akapity" + } + }, + "json": { + "label": "Generator JSON", + "description": "Generuj losowe dane JSON z różnymi typami pól", + "fields": "Pola", + "fieldName": "Nazwa pola", + "selectType": "Wybierz typ", + "addField": "Dodaj pole", + "rowCount": "Liczba wierszy", + "maxRows": "Maks 1000", + "categories": { + "general": "Ogólne", + "person": "Osoba", + "internet": "Internet", + "location": "Lokalizacja", + "finance": "Finanse", + "commerce": "Handel", + "company": "Firma", + "lorem": "Lorem", + "date": "Data", + "number": "Liczba", + "phone": "Telefon", + "image": "Obraz" + }, + "types": { + "rowNumber": "Numer wiersza", + "firstName": "Imię", + "lastName": "Nazwisko", + "fullName": "Pełne imię", + "gender": "Płeć", + "jobTitle": "Stanowisko", + "email": "Adres e-mail", + "username": "Nazwa użytkownika", + "password": "Hasło", + "url": "URL", + "ipv4": "Adres IP v4", + "ipv6": "Adres IP v6", + "userAgent": "User Agent", + "city": "Miasto", + "country": "Kraj", + "streetAddress": "Adres", + "zipCode": "Kod pocztowy", + "latitude": "Szerokość geograficzna", + "longitude": "Długość geograficzna", + "amount": "Kwota", + "currencyCode": "Kod waluty", + "creditCardNumber": "Numer karty kredytowej", + "productName": "Nazwa produktu", + "price": "Cena", + "department": "Dział", + "companyName": "Nazwa firmy", + "catchPhrase": "Hasło reklamowe", + "word": "Słowo", + "sentence": "Zdanie", + "paragraph": "Akapit", + "past": "Przeszła data", + "future": "Przyszła data", + "recent": "Ostatnia data", + "birthdate": "Data urodzenia", + "int": "Liczba całkowita", + "float": "Liczba zmiennoprzecinkowa", + "boolean": "Wartość logiczna", + "phoneNumber": "Numer telefonu", + "imei": "IMEI", + "avatar": "URL awatara", + "imageUrl": "URL obrazu" + } + } + }, "converters": { "label": "Konwertery", "caseConverter": { diff --git a/src/main/i18n/locales/pl_PL/messages.json b/src/main/i18n/locales/pl_PL/messages.json index 7a8edc94..56ca9345 100644 --- a/src/main/i18n/locales/pl_PL/messages.json +++ b/src/main/i18n/locales/pl_PL/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Pomyślnie przeprowadzono migrację bazy danych." + "copied": "Skopiowano do schowka", + "migrate": "Pomyślnie przeprowadzono migrację bazy danych.", + "backup": { + "created": "Kopia zapasowa została pomyślnie utworzona.", + "restored": "Kopia zapasowa została pomyślnie przywrócona.", + "deleted": "Kopia zapasowa została pomyślnie usunięta." + } }, "warning": { "noUndo": "Tej operacji nie można cofnąć.", diff --git a/src/main/i18n/locales/pt_BR/devtools.json b/src/main/i18n/locales/pt_BR/devtools.json index 2b39d164..363779ed 100644 --- a/src/main/i18n/locales/pt_BR/devtools.json +++ b/src/main/i18n/locales/pt_BR/devtools.json @@ -1,5 +1,86 @@ { "label": "Ferramentas de Desenvolvimento", + "generators": { + "label": "Geradores", + "lorem": { + "label": "Gerador Lorem Ipsum", + "description": "Gerar texto de espaço reservado", + "selectType": "Selecionar tipo", + "maxCount": "Máx {{count}}", + "types": { + "words": "Palavras", + "sentences": "Frases", + "paragraphs": "Parágrafos" + } + }, + "json": { + "label": "Gerador JSON", + "description": "Gerar dados JSON aleatórios com vários tipos de campos", + "fields": "Campos", + "fieldName": "Nome do campo", + "selectType": "Selecionar tipo", + "addField": "Adicionar campo", + "rowCount": "Número de linhas", + "maxRows": "Máx 1000", + "categories": { + "general": "Geral", + "person": "Pessoa", + "internet": "Internet", + "location": "Localização", + "finance": "Finanças", + "commerce": "Comércio", + "company": "Empresa", + "lorem": "Lorem", + "date": "Data", + "number": "Número", + "phone": "Telefone", + "image": "Imagem" + }, + "types": { + "rowNumber": "Número da linha", + "firstName": "Primeiro nome", + "lastName": "Sobrenome", + "fullName": "Nome completo", + "gender": "Gênero", + "jobTitle": "Cargo", + "email": "Endereço de e-mail", + "username": "Nome de usuário", + "password": "Senha", + "url": "URL", + "ipv4": "Endereço IP v4", + "ipv6": "Endereço IP v6", + "userAgent": "User Agent", + "city": "Cidade", + "country": "País", + "streetAddress": "Endereço", + "zipCode": "CEP", + "latitude": "Latitude", + "longitude": "Longitude", + "amount": "Valor", + "currencyCode": "Código da moeda", + "creditCardNumber": "Número do cartão de crédito", + "productName": "Nome do produto", + "price": "Preço", + "department": "Departamento", + "companyName": "Nome da empresa", + "catchPhrase": "Slogan", + "word": "Palavra", + "sentence": "Frase", + "paragraph": "Parágrafo", + "past": "Data passada", + "future": "Data futura", + "recent": "Data recente", + "birthdate": "Data de nascimento", + "int": "Inteiro", + "float": "Ponto flutuante", + "boolean": "Booleano", + "phoneNumber": "Número de telefone", + "imei": "IMEI", + "avatar": "URL do avatar", + "imageUrl": "URL da imagem" + } + } + }, "converters": { "label": "Conversores", "caseConverter": { diff --git a/src/main/i18n/locales/pt_BR/messages.json b/src/main/i18n/locales/pt_BR/messages.json index 534888e5..d7182b24 100644 --- a/src/main/i18n/locales/pt_BR/messages.json +++ b/src/main/i18n/locales/pt_BR/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "DB migrado com sucesso." + "copied": "Copiado para a área de transferência", + "migrate": "DB migrado com sucesso.", + "backup": { + "created": "Backup criado com sucesso.", + "restored": "Backup restaurado com sucesso.", + "deleted": "Backup excluído com sucesso." + } }, "warning": { "noUndo": "Você não pode desfazer esta ação.", diff --git a/src/main/i18n/locales/ro_RO/devtools.json b/src/main/i18n/locales/ro_RO/devtools.json index 5e022d3d..b1b5555c 100644 --- a/src/main/i18n/locales/ro_RO/devtools.json +++ b/src/main/i18n/locales/ro_RO/devtools.json @@ -1,5 +1,86 @@ { "label": "Instrumente pentru Dezvoltatori", + "generators": { + "label": "Generatoare", + "lorem": { + "label": "Generator Lorem Ipsum", + "description": "Generează text substituent", + "selectType": "Selectează tipul", + "maxCount": "Max {{count}}", + "types": { + "words": "Cuvinte", + "sentences": "Propoziții", + "paragraphs": "Paragrafe" + } + }, + "json": { + "label": "Generator JSON", + "description": "Generează date JSON aleatorii cu diferite tipuri de câmpuri", + "fields": "Câmpuri", + "fieldName": "Nume câmp", + "selectType": "Selectează tipul", + "addField": "Adaugă câmp", + "rowCount": "Număr de rânduri", + "maxRows": "Max 1000", + "categories": { + "general": "General", + "person": "Persoană", + "internet": "Internet", + "location": "Locație", + "finance": "Finanțe", + "commerce": "Comerț", + "company": "Companie", + "lorem": "Lorem", + "date": "Dată", + "number": "Număr", + "phone": "Telefon", + "image": "Imagine" + }, + "types": { + "rowNumber": "Număr rând", + "firstName": "Prenume", + "lastName": "Nume de familie", + "fullName": "Nume complet", + "gender": "Gen", + "jobTitle": "Titlu job", + "email": "Adresă email", + "username": "Nume utilizator", + "password": "Parolă", + "url": "URL", + "ipv4": "Adresă IP v4", + "ipv6": "Adresă IP v6", + "userAgent": "User Agent", + "city": "Oraș", + "country": "Țară", + "streetAddress": "Adresă stradă", + "zipCode": "Cod poștal", + "latitude": "Latitudine", + "longitude": "Longitudine", + "amount": "Sumă", + "currencyCode": "Cod monedă", + "creditCardNumber": "Număr card credit", + "productName": "Nume produs", + "price": "Preț", + "department": "Departament", + "companyName": "Nume companie", + "catchPhrase": "Slogan", + "word": "Cuvânt", + "sentence": "Propoziție", + "paragraph": "Paragraf", + "past": "Dată trecută", + "future": "Dată viitoare", + "recent": "Dată recentă", + "birthdate": "Dată naștere", + "int": "Întreg", + "float": "Zecimal", + "boolean": "Boolean", + "phoneNumber": "Număr telefon", + "imei": "IMEI", + "avatar": "URL avatar", + "imageUrl": "URL imagine" + } + } + }, "converters": { "label": "Convertoare", "caseConverter": { diff --git a/src/main/i18n/locales/ro_RO/messages.json b/src/main/i18n/locales/ro_RO/messages.json index 606f96bb..66aa0225 100644 --- a/src/main/i18n/locales/ro_RO/messages.json +++ b/src/main/i18n/locales/ro_RO/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "DB a fost migrat cu succes." + "copied": "Copiat în clipboard", + "migrate": "DB a fost migrat cu succes.", + "backup": { + "created": "Backup creat cu succes.", + "restored": "Backup restaurat cu succes.", + "deleted": "Backup șters cu succes." + } }, "warning": { "noUndo": "Nu puteți anula această acțiune.", diff --git a/src/main/i18n/locales/ru_RU/devtools.json b/src/main/i18n/locales/ru_RU/devtools.json index 47229069..ceb6719b 100644 --- a/src/main/i18n/locales/ru_RU/devtools.json +++ b/src/main/i18n/locales/ru_RU/devtools.json @@ -1,5 +1,86 @@ { "label": "Инструменты разработчика", + "generators": { + "label": "Генераторы", + "lorem": { + "label": "Lorem Ipsum генератор", + "description": "Генерация текста-заполнителя", + "selectType": "Выберите тип", + "maxCount": "Максимум {{count}}", + "types": { + "words": "Слова", + "sentences": "Предложения", + "paragraphs": "Параграфы" + } + }, + "json": { + "label": "JSON генератор", + "description": "Генерация случайных JSON данных с различными типами полей", + "fields": "Поля", + "fieldName": "Имя поля", + "selectType": "Выберите тип", + "addField": "Добавить поле", + "rowCount": "Количество строк", + "maxRows": "Максимум 1000", + "categories": { + "general": "Общие", + "person": "Персона", + "internet": "Интернет", + "location": "Локация", + "finance": "Финансы", + "commerce": "Торговля", + "company": "Компания", + "lorem": "Lorem", + "date": "Дата", + "number": "Число", + "phone": "Телефон", + "image": "Изображение" + }, + "types": { + "rowNumber": "Номер строки", + "firstName": "Имя", + "lastName": "Фамилия", + "fullName": "Полное имя", + "gender": "Пол", + "jobTitle": "Должность", + "email": "Email адрес", + "username": "Имя пользователя", + "password": "Пароль", + "url": "URL", + "ipv4": "IP адрес v4", + "ipv6": "IP адрес v6", + "userAgent": "User Agent", + "city": "Город", + "country": "Страна", + "streetAddress": "Адрес", + "zipCode": "Почтовый индекс", + "latitude": "Широта", + "longitude": "Долгота", + "amount": "Сумма", + "currencyCode": "Код валюты", + "creditCardNumber": "Номер кредитной карты", + "productName": "Название товара", + "price": "Цена", + "department": "Отдел", + "companyName": "Название компании", + "catchPhrase": "Слоган", + "word": "Слово", + "sentence": "Предложение", + "paragraph": "Параграф", + "past": "Прошедшая дата", + "future": "Будущая дата", + "recent": "Недавняя дата", + "birthdate": "Дата рождения", + "int": "Целое число", + "float": "Дробное число", + "boolean": "Булево", + "phoneNumber": "Номер телефона", + "imei": "IMEI", + "avatar": "URL аватара", + "imageUrl": "URL изображения" + } + } + }, "converters": { "label": "Конвертеры", "caseConverter": { diff --git a/src/main/i18n/locales/ru_RU/messages.json b/src/main/i18n/locales/ru_RU/messages.json index a7cddd62..a3ddcd27 100644 --- a/src/main/i18n/locales/ru_RU/messages.json +++ b/src/main/i18n/locales/ru_RU/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "База данных успешно мигрирована." + "copied": "Скопировано в буфер обмена", + "migrate": "База данных успешно мигрирована.", + "backup": { + "created": "Резервная копия успешно создана.", + "restored": "Резервная копия успешно восстановлена.", + "deleted": "Резервная копия успешно удалена." + } }, "warning": { "noUndo": "Это действие нельзя отменить.", diff --git a/src/main/i18n/locales/tr_TR/devtools.json b/src/main/i18n/locales/tr_TR/devtools.json index 8c62119d..b41e74d0 100644 --- a/src/main/i18n/locales/tr_TR/devtools.json +++ b/src/main/i18n/locales/tr_TR/devtools.json @@ -1,5 +1,86 @@ { "label": "Geliştirici Araçları", + "generators": { + "label": "Üreteçler", + "lorem": { + "label": "Lorem Ipsum Üreteci", + "description": "Lorem Ipsum yer tutucu metni oluştur", + "selectType": "Tür seç", + "maxCount": "Maks {{count}}", + "types": { + "words": "Kelimeler", + "sentences": "Cümleler", + "paragraphs": "Paragraflar" + } + }, + "json": { + "label": "JSON Üreteci", + "description": "Çeşitli alan türleriyle rastgele JSON verileri oluştur", + "fields": "Alanlar", + "fieldName": "Alan adı", + "selectType": "Tür seç", + "addField": "Alan ekle", + "rowCount": "Satır sayısı", + "maxRows": "Maks 1000", + "categories": { + "general": "Genel", + "person": "Kişi", + "internet": "İnternet", + "location": "Konum", + "finance": "Finans", + "commerce": "Ticaret", + "company": "Şirket", + "lorem": "Lorem", + "date": "Tarih", + "number": "Sayı", + "phone": "Telefon", + "image": "Resim" + }, + "types": { + "rowNumber": "Satır numarası", + "firstName": "Ad", + "lastName": "Soyad", + "fullName": "Tam ad", + "gender": "Cinsiyet", + "jobTitle": "İş unvanı", + "email": "E-posta adresi", + "username": "Kullanıcı adı", + "password": "Şifre", + "url": "URL", + "ipv4": "IP adresi v4", + "ipv6": "IP adresi v6", + "userAgent": "User Agent", + "city": "Şehir", + "country": "Ülke", + "streetAddress": "Adres", + "zipCode": "Posta kodu", + "latitude": "Enlem", + "longitude": "Boylam", + "amount": "Miktar", + "currencyCode": "Para birimi kodu", + "creditCardNumber": "Kredi kartı numarası", + "productName": "Ürün adı", + "price": "Fiyat", + "department": "Departman", + "companyName": "Şirket adı", + "catchPhrase": "Slogan", + "word": "Kelime", + "sentence": "Cümle", + "paragraph": "Paragraf", + "past": "Geçmiş tarih", + "future": "Gelecek tarih", + "recent": "Son tarih", + "birthdate": "Doğum tarihi", + "int": "Tamsayı", + "float": "Ondalık sayı", + "boolean": "Boolean", + "phoneNumber": "Telefon numarası", + "imei": "IMEI", + "avatar": "Avatar URL'si", + "imageUrl": "Resim URL'si" + } + } + }, "converters": { "label": "Dönüştürücüler", "caseConverter": { diff --git a/src/main/i18n/locales/tr_TR/messages.json b/src/main/i18n/locales/tr_TR/messages.json index 627e5f10..72fc655c 100644 --- a/src/main/i18n/locales/tr_TR/messages.json +++ b/src/main/i18n/locales/tr_TR/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "Database başarıyla taşındı." + "copied": "Panoya kopyalandı", + "migrate": "Database başarıyla taşındı.", + "backup": { + "created": "Yedek başarıyla oluşturuldu.", + "restored": "Yedek başarıyla geri yüklendi.", + "deleted": "Yedek başarıyla silindi." + } }, "warning": { "noUndo": "Bu işlemi geri alamazsınız.", diff --git a/src/main/i18n/locales/uk_UA/devtools.json b/src/main/i18n/locales/uk_UA/devtools.json index ae4ac63d..0b7fd799 100644 --- a/src/main/i18n/locales/uk_UA/devtools.json +++ b/src/main/i18n/locales/uk_UA/devtools.json @@ -1,5 +1,86 @@ { "label": "Інструменти розробника", + "generators": { + "label": "Генератори", + "lorem": { + "label": "Генератор Lorem Ipsum", + "description": "Генерація тексту-заповнювача", + "selectType": "Виберіть тип", + "maxCount": "Макс {{count}}", + "types": { + "words": "Слова", + "sentences": "Речення", + "paragraphs": "Параграфи" + } + }, + "json": { + "label": "JSON генератор", + "description": "Генерувати випадкові JSON дані з різними типами полів", + "fields": "Поля", + "fieldName": "Назва поля", + "selectType": "Обрати тип", + "addField": "Додати поле", + "rowCount": "Кількість рядків", + "maxRows": "Макс 1000", + "categories": { + "general": "Загальне", + "person": "Особа", + "internet": "Інтернет", + "location": "Місцезнаходження", + "finance": "Фінанси", + "commerce": "Торгівля", + "company": "Компанія", + "lorem": "Lorem", + "date": "Дата", + "number": "Число", + "phone": "Телефон", + "image": "Зображення" + }, + "types": { + "rowNumber": "Номер рядка", + "firstName": "Ім'я", + "lastName": "Прізвище", + "fullName": "Повне ім'я", + "gender": "Стать", + "jobTitle": "Посада", + "email": "Адреса електронної пошти", + "username": "Ім'я користувача", + "password": "Пароль", + "url": "URL", + "ipv4": "IP адреса v4", + "ipv6": "IP адреса v6", + "userAgent": "User Agent", + "city": "Місто", + "country": "Країна", + "streetAddress": "Адреса", + "zipCode": "Поштовий індекс", + "latitude": "Широта", + "longitude": "Довгота", + "amount": "Сума", + "currencyCode": "Код валюти", + "creditCardNumber": "Номер кредитної картки", + "productName": "Назва товару", + "price": "Ціна", + "department": "Відділ", + "companyName": "Назва компанії", + "catchPhrase": "Слоган", + "word": "Слово", + "sentence": "Речення", + "paragraph": "Абзац", + "past": "Минула дата", + "future": "Майбутня дата", + "recent": "Недавня дата", + "birthdate": "Дата народження", + "int": "Ціле число", + "float": "Дробове число", + "boolean": "Булевий", + "phoneNumber": "Номер телефону", + "imei": "IMEI", + "avatar": "URL аватара", + "imageUrl": "URL зображення" + } + } + }, "converters": { "label": "Конвертери", "caseConverter": { diff --git a/src/main/i18n/locales/uk_UA/messages.json b/src/main/i18n/locales/uk_UA/messages.json index fc43c08e..f33aa087 100644 --- a/src/main/i18n/locales/uk_UA/messages.json +++ b/src/main/i18n/locales/uk_UA/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "База даних успішно мігрована." + "copied": "Скопійовано в буфер обміну", + "migrate": "База даних успішно мігрована.", + "backup": { + "created": "Резервну копію успішно створено.", + "restored": "Резервну копію успішно відновлено.", + "deleted": "Резервну копію успішно видалено." + } }, "warning": { "noUndo": "Ви не зможете скасувати цю дію.", diff --git a/src/main/i18n/locales/zh_CN/devtools.json b/src/main/i18n/locales/zh_CN/devtools.json index ff9748b8..ab4a5122 100644 --- a/src/main/i18n/locales/zh_CN/devtools.json +++ b/src/main/i18n/locales/zh_CN/devtools.json @@ -1,5 +1,86 @@ { "label": "开发者工具", + "generators": { + "label": "生成器", + "lorem": { + "label": "Lorem Ipsum 生成器", + "description": "生成占位符文本", + "selectType": "选择类型", + "maxCount": "最大 {{count}}", + "types": { + "words": "单词", + "sentences": "句子", + "paragraphs": "段落" + } + }, + "json": { + "label": "JSON 生成器", + "description": "使用各种字段类型生成随机 JSON 数据", + "fields": "字段", + "fieldName": "字段名称", + "selectType": "选择类型", + "addField": "添加字段", + "rowCount": "行数", + "maxRows": "最大 1000", + "categories": { + "general": "通用", + "person": "人员", + "internet": "互联网", + "location": "位置", + "finance": "财务", + "commerce": "商业", + "company": "公司", + "lorem": "Lorem", + "date": "日期", + "number": "数字", + "phone": "电话", + "image": "图片" + }, + "types": { + "rowNumber": "行号", + "firstName": "名", + "lastName": "姓", + "fullName": "全名", + "gender": "性别", + "jobTitle": "职位", + "email": "电子邮件地址", + "username": "用户名", + "password": "密码", + "url": "URL", + "ipv4": "IP 地址 v4", + "ipv6": "IP 地址 v6", + "userAgent": "User Agent", + "city": "城市", + "country": "国家", + "streetAddress": "街道地址", + "zipCode": "邮政编码", + "latitude": "纬度", + "longitude": "经度", + "amount": "金额", + "currencyCode": "货币代码", + "creditCardNumber": "信用卡号", + "productName": "产品名称", + "price": "价格", + "department": "部门", + "companyName": "公司名称", + "catchPhrase": "标语", + "word": "单词", + "sentence": "句子", + "paragraph": "段落", + "past": "过去日期", + "future": "未来日期", + "recent": "最近日期", + "birthdate": "出生日期", + "int": "整数", + "float": "浮点数", + "boolean": "布尔值", + "phoneNumber": "电话号码", + "imei": "IMEI", + "avatar": "头像 URL", + "imageUrl": "图片 URL" + } + } + }, "converters": { "label": "转换器", "caseConverter": { diff --git a/src/main/i18n/locales/zh_CN/messages.json b/src/main/i18n/locales/zh_CN/messages.json index ccf2df7f..627a563f 100644 --- a/src/main/i18n/locales/zh_CN/messages.json +++ b/src/main/i18n/locales/zh_CN/messages.json @@ -11,7 +11,13 @@ ] }, "success": { - "migrate": "数据库迁移成功。" + "copied": "已复制到剪贴板", + "migrate": "数据库迁移成功。", + "backup": { + "created": "备份创建成功。", + "restored": "备份恢复成功。", + "deleted": "备份删除成功。" + } }, "warning": { "noUndo": "此操作无法撤消。", diff --git a/src/main/i18n/locales/zh_HK/devtools.json b/src/main/i18n/locales/zh_HK/devtools.json index 042f4790..00c5cd0d 100644 --- a/src/main/i18n/locales/zh_HK/devtools.json +++ b/src/main/i18n/locales/zh_HK/devtools.json @@ -1,5 +1,86 @@ { "label": "開發者工具", + "generators": { + "label": "生成器", + "lorem": { + "label": "Lorem Ipsum 生成器", + "description": "生成占位符文字", + "selectType": "選擇類型", + "maxCount": "最大 {{count}}", + "types": { + "words": "單詞", + "sentences": "句子", + "paragraphs": "段落" + } + }, + "json": { + "label": "JSON 生成器", + "description": "使用各種欄位類型產生隨機 JSON 資料", + "fields": "欄位", + "fieldName": "欄位名稱", + "selectType": "選擇類型", + "addField": "新增欄位", + "rowCount": "列數", + "maxRows": "最大 1000", + "categories": { + "general": "一般", + "person": "人員", + "internet": "網際網路", + "location": "位置", + "finance": "財務", + "commerce": "商業", + "company": "公司", + "lorem": "Lorem", + "date": "日期", + "number": "數字", + "phone": "電話", + "image": "圖片" + }, + "types": { + "rowNumber": "列號", + "firstName": "名", + "lastName": "姓", + "fullName": "全名", + "gender": "性別", + "jobTitle": "職稱", + "email": "電子郵件地址", + "username": "使用者名稱", + "password": "密碼", + "url": "URL", + "ipv4": "IP 地址 v4", + "ipv6": "IP 地址 v6", + "userAgent": "User Agent", + "city": "城市", + "country": "國家", + "streetAddress": "街道地址", + "zipCode": "郵遞區號", + "latitude": "緯度", + "longitude": "經度", + "amount": "金額", + "currencyCode": "貨幣代碼", + "creditCardNumber": "信用卡號", + "productName": "產品名稱", + "price": "價格", + "department": "部門", + "companyName": "公司名稱", + "catchPhrase": "標語", + "word": "單字", + "sentence": "句子", + "paragraph": "段落", + "past": "過去日期", + "future": "未來日期", + "recent": "最近日期", + "birthdate": "出生日期", + "int": "整數", + "float": "浮點數", + "boolean": "布林值", + "phoneNumber": "電話號碼", + "imei": "IMEI", + "avatar": "頭像 URL", + "imageUrl": "圖片 URL" + } + } + }, "converters": { "label": "轉換器", "caseConverter": { diff --git a/src/main/i18n/locales/zh_HK/messages.json b/src/main/i18n/locales/zh_HK/messages.json index 21660b6a..b559c4cb 100644 --- a/src/main/i18n/locales/zh_HK/messages.json +++ b/src/main/i18n/locales/zh_HK/messages.json @@ -11,6 +11,11 @@ ] }, "success": { + "copied": "已複製", + "backup": { + "created": "備份已創建", + "restored": "備份已恢復" + }, "migrate": "資料庫遷移成功。" }, "warning": { diff --git a/src/main/i18n/locales/zh_TW/devtools.json b/src/main/i18n/locales/zh_TW/devtools.json index 29e436c2..32cbc17a 100644 --- a/src/main/i18n/locales/zh_TW/devtools.json +++ b/src/main/i18n/locales/zh_TW/devtools.json @@ -1,5 +1,86 @@ { "label": "開發者工具", + "generators": { + "label": "生成器", + "lorem": { + "label": "Lorem Ipsum 生成器", + "description": "生成占位符文字", + "selectType": "選擇類型", + "maxCount": "最大 {{count}}", + "types": { + "words": "單詞", + "sentences": "句子", + "paragraphs": "段落" + } + }, + "json": { + "label": "JSON 生成器", + "description": "使用各種欄位類型產生隨機 JSON 資料", + "fields": "欄位", + "fieldName": "欄位名稱", + "selectType": "選擇類型", + "addField": "新增欄位", + "rowCount": "列數", + "maxRows": "最大 1000", + "categories": { + "general": "一般", + "person": "人員", + "internet": "網際網路", + "location": "位置", + "finance": "財務", + "commerce": "商業", + "company": "公司", + "lorem": "Lorem", + "date": "日期", + "number": "數字", + "phone": "電話", + "image": "圖片" + }, + "types": { + "rowNumber": "列號", + "firstName": "名", + "lastName": "姓", + "fullName": "全名", + "gender": "性別", + "jobTitle": "職稱", + "email": "電子郵件地址", + "username": "使用者名稱", + "password": "密碼", + "url": "URL", + "ipv4": "IP 地址 v4", + "ipv6": "IP 地址 v6", + "userAgent": "User Agent", + "city": "城市", + "country": "國家", + "streetAddress": "街道地址", + "zipCode": "郵遞區號", + "latitude": "緯度", + "longitude": "經度", + "amount": "金額", + "currencyCode": "貨幣代碼", + "creditCardNumber": "信用卡號", + "productName": "產品名稱", + "price": "價格", + "department": "部門", + "companyName": "公司名稱", + "catchPhrase": "標語", + "word": "單字", + "sentence": "句子", + "paragraph": "段落", + "past": "過去日期", + "future": "未來日期", + "recent": "最近日期", + "birthdate": "出生日期", + "int": "整數", + "float": "浮點數", + "boolean": "布林值", + "phoneNumber": "電話號碼", + "imei": "IMEI", + "avatar": "頭像 URL", + "imageUrl": "圖片 URL" + } + } + }, "converters": { "label": "轉換器", "caseConverter": { diff --git a/src/main/i18n/locales/zh_TW/messages.json b/src/main/i18n/locales/zh_TW/messages.json index c4b1884f..af4de237 100644 --- a/src/main/i18n/locales/zh_TW/messages.json +++ b/src/main/i18n/locales/zh_TW/messages.json @@ -11,6 +11,11 @@ ] }, "success": { + "copied": "已複製", + "backup": { + "created": "備份已建立", + "restored": "備份已還原" + }, "migrate": "資料庫遷移成功。" }, "warning": { diff --git a/src/main/index.ts b/src/main/index.ts index 1b341d41..56e52e07 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -90,7 +90,7 @@ else { } try { - initApi() + await initApi() } catch (error) { log('Error initializing API', error) diff --git a/src/main/utils/index.ts b/src/main/utils/index.ts index 192f20fc..a5ee5f2d 100644 --- a/src/main/utils/index.ts +++ b/src/main/utils/index.ts @@ -12,3 +12,8 @@ export function log(context: string, error: unknown): void { stack, }) } + +export function importEsm(specifier: string) { + // eslint-disable-next-line no-new-func + return new Function('s', 'return import(s)')(specifier) as Promise +} diff --git a/src/renderer/components/devtools/converters/Base64Converter.vue b/src/renderer/components/devtools/converters/Base64Converter.vue index 4dc45dbf..f5c5069c 100644 --- a/src/renderer/components/devtools/converters/Base64Converter.vue +++ b/src/renderer/components/devtools/converters/Base64Converter.vue @@ -1,12 +1,12 @@