From 2c2b302de101c72d20406007b2cb200d3ed8e232 Mon Sep 17 00:00:00 2001 From: sharevb Date: Sun, 16 Jun 2024 12:55:53 +0200 Subject: [PATCH 1/2] feat(new tool): JSON To Schema Convert JSON data to JSON Schema, MySQL DDL, Mongoose Schema, Google BigQuery schema or ClickHouse Table Schema --- components.d.ts | 1 + package.json | 1 + pnpm-lock.yaml | 35 ++++++-- src/composable/queryParams.ts | 33 ++++++- src/tools/index.ts | 2 + src/tools/json-to-schema/generate-schema.d.ts | 8 ++ src/tools/json-to-schema/index.ts | 12 +++ src/tools/json-to-schema/json-to-schema.vue | 86 +++++++++++++++++++ 8 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 src/tools/json-to-schema/generate-schema.d.ts create mode 100644 src/tools/json-to-schema/index.ts create mode 100644 src/tools/json-to-schema/json-to-schema.vue diff --git a/components.d.ts b/components.d.ts index f2c3146f..0d0743dd 100644 --- a/components.d.ts +++ b/components.d.ts @@ -109,6 +109,7 @@ declare module '@vue/runtime-core' { JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default'] JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default'] JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default'] + JsonToSchema: typeof import('./src/tools/json-to-schema/json-to-schema.vue')['default'] JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default'] JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default'] JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default'] diff --git a/package.json b/package.json index c6cb7757..7bfbd487 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "figlet": "^1.7.0", "figue": "^1.2.0", "fuse.js": "^6.6.2", + "generate-schema": "^2.6.0", "highlight.js": "^11.7.0", "iarna-toml-esm": "^3.0.5", "ibantools": "^4.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8619d8c0..07d2a741 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ dependencies: fuse.js: specifier: ^6.6.2 version: 6.6.2 + generate-schema: + specifier: ^2.6.0 + version: 2.6.0 highlight.js: specifier: ^11.7.0 version: 11.7.0 @@ -3354,7 +3357,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.8.0(vue@3.3.4) + '@vueuse/shared': 10.11.0(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3987,19 +3990,19 @@ packages: - vue dev: false - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} + /@vueuse/shared@10.11.0(vue@3.3.4): + resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==} dependencies: - vue-demi: 0.14.5(vue@3.3.4) + vue-demi: 0.14.8(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.8.0(vue@3.3.4): - resolution: {integrity: sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==} + /@vueuse/shared@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} dependencies: - vue-demi: 0.14.7(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5765,6 +5768,14 @@ packages: engines: {node: '>=10'} dev: false + /generate-schema@2.6.0: + resolution: {integrity: sha512-EUBKfJNzT8f91xUk5X5gKtnbdejZeE065UAJ3BCzE8VEbvwKI9Pm5jaWmqVeK1MYc1g5weAVFDTSJzN7ymtTqA==} + hasBin: true + dependencies: + commander: 2.20.3 + type-of-is: 3.5.1 + dev: false + /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -8555,6 +8566,11 @@ packages: engines: {node: '>=12.20'} dev: false + /type-of-is@3.5.1: + resolution: {integrity: sha512-SOnx8xygcAh8lvDU2exnK2bomASfNjzB3Qz71s2tw9QnX8fkAo7aC+D0H7FV0HjRKj94CKV2Hi71kVkkO6nOxg==} + engines: {node: '>=0.10.5'} + dev: false + /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} @@ -9158,8 +9174,8 @@ packages: vue: 3.3.4 dev: false - /vue-demi@0.14.7(vue@3.3.4): - resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} + /vue-demi@0.14.8(vue@3.3.4): + resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true @@ -9449,6 +9465,7 @@ packages: /workbox-google-analytics@7.0.0: resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} + deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained dependencies: workbox-background-sync: 7.0.0 workbox-core: 7.0.0 diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9699abbc..7cc8cc0d 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -1,7 +1,8 @@ import { useRouteQuery } from '@vueuse/router'; import { computed } from 'vue'; +import { useStorage } from '@vueuse/core'; -export { useQueryParam }; +export { useQueryParam, useQueryParamOrStorage }; const transformers = { number: { @@ -16,6 +17,12 @@ const transformers = { fromQuery: (value: string) => value.toLowerCase() === 'true', toQuery: (value: boolean) => (value ? 'true' : 'false'), }, + object: { + fromQuery: (value: string) => { + return JSON.parse(value); + }, + toQuery: (value: object) => JSON.stringify(value), + }, }; function useQueryParam({ name, defaultValue }: { name: string; defaultValue: T }) { @@ -33,3 +40,27 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }, }); } + +function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) { + const type = typeof defaultValue; + const transformer = transformers[type as keyof typeof transformers] ?? transformers.string; + + const storageRef = useStorage(storageName, defaultValue); + const proxyDefaultValue = transformer.toQuery(defaultValue as never); + const proxy = useRouteQuery(name, proxyDefaultValue); + + const r = ref(defaultValue); + + watch(r, + (value) => { + proxy.value = transformer.toQuery(value as never); + storageRef.value = value as never; + }, + { deep: true }); + + r.value = (proxy.value && proxy.value !== proxyDefaultValue + ? transformer.fromQuery(proxy.value) as unknown as T + : storageRef.value as T) as never; + + return r; +} diff --git a/src/tools/index.ts b/src/tools/index.ts index aa861c93..5cb022b6 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer'; import { tool as textToUnicode } from './text-to-unicode'; import { tool as safelinkDecoder } from './safelink-decoder'; +import { tool as jsonToSchema } from './json-to-schema'; import { tool as pdfSignatureChecker } from './pdf-signature-checker'; import { tool as numeronymGenerator } from './numeronym-generator'; import { tool as macAddressGenerator } from './mac-address-generator'; @@ -148,6 +149,7 @@ export const toolsByCategory: ToolCategory[] = [ dockerRunToDockerComposeConverter, xmlFormatter, yamlViewer, + jsonToSchema, ], }, { diff --git a/src/tools/json-to-schema/generate-schema.d.ts b/src/tools/json-to-schema/generate-schema.d.ts new file mode 100644 index 00000000..5b081983 --- /dev/null +++ b/src/tools/json-to-schema/generate-schema.d.ts @@ -0,0 +1,8 @@ +declare module 'generate-schema' { + function generic(jsonObject: object); + function mongoose(jsonObject: object); + function bigquery(jsonObject: object); + function json(title: string, jsonObject: object); + function mysql(tableName: string, jsonObject: object); + function clickhouse(tableName: string, jsonObject: object, dateField: string); +} \ No newline at end of file diff --git a/src/tools/json-to-schema/index.ts b/src/tools/json-to-schema/index.ts new file mode 100644 index 00000000..5252c6a2 --- /dev/null +++ b/src/tools/json-to-schema/index.ts @@ -0,0 +1,12 @@ +import { Braces } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Json to Schema', + path: '/json-to-schema', + description: 'Convert JSON data to JSON Schema, MySQL DDL, Mongoose Schema, Google BigQuery schema or ClickHouse Table Schema', + keywords: ['json', 'schema', 'mysql', 'sql', 'ddl', 'mongoose', 'bigquery', 'clickhouse', 'table'], + component: () => import('./json-to-schema.vue'), + icon: Braces, + createdAt: new Date('2024-05-11'), +}); diff --git a/src/tools/json-to-schema/json-to-schema.vue b/src/tools/json-to-schema/json-to-schema.vue new file mode 100644 index 00000000..18e382e2 --- /dev/null +++ b/src/tools/json-to-schema/json-to-schema.vue @@ -0,0 +1,86 @@ + + + From f76aaa210facc7427833433e35f047fe14057848 Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 9 Jun 2024 12:32:10 +0200 Subject: [PATCH 2/2] chore: fix strange corepack message Fix corepack claiming strange thing : UsageError: This project is configured to use yarn because /home/runner/work/it-tools/it-tools/package.json has a "packageManager" field --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7bfbd487..58c5062d 100644 --- a/package.json +++ b/package.json @@ -139,5 +139,6 @@ "vitest": "^0.34.0", "workbox-window": "^7.0.0", "zx": "^7.2.1" - } + }, + "packageManager": "pnpm@8.15.3" }