From 0d9f6aa01b27fd19c24dbfe90f0145817e4db902 Mon Sep 17 00:00:00 2001 From: sharevb Date: Fri, 23 Aug 2024 21:45:29 +0200 Subject: [PATCH 1/2] feat(new tool): jq/JSONPath tester Fix #273 and #672 --- components.d.ts | 9 ++- package.json | 3 + pnpm-lock.yaml | 111 ++++++++++++++++++++++++++---- src/tools/index.ts | 2 + src/tools/jq-tester/index.ts | 12 ++++ src/tools/jq-tester/jq-tester.vue | 83 ++++++++++++++++++++++ 6 files changed, 202 insertions(+), 18 deletions(-) create mode 100644 src/tools/jq-tester/index.ts create mode 100644 src/tools/jq-tester/jq-tester.vue diff --git a/components.d.ts b/components.d.ts index 89f41f80..bd29051c 100644 --- a/components.d.ts +++ b/components.d.ts @@ -107,6 +107,7 @@ declare module '@vue/runtime-core' { Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default'] Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default'] Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default'] + JqTester: typeof import('./src/tools/jq-tester/jq-tester.vue')['default'] 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'] @@ -133,18 +134,16 @@ declare module '@vue/runtime-core' { NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NEllipsis: typeof import('naive-ui')['NEllipsis'] - NForm: typeof import('naive-ui')['NForm'] - NFormItem: typeof import('naive-ui')['NFormItem'] NH1: typeof import('naive-ui')['NH1'] NH3: typeof import('naive-ui')['NH3'] NIcon: typeof import('naive-ui')['NIcon'] - NInputNumber: typeof import('naive-ui')['NInputNumber'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] + NRadio: typeof import('naive-ui')['NRadio'] + NRadioGroup: typeof import('naive-ui')['NRadioGroup'] NScrollbar: typeof import('naive-ui')['NScrollbar'] - NSlider: typeof import('naive-ui')['NSlider'] - NSwitch: typeof import('naive-ui')['NSwitch'] + NSpace: typeof import('naive-ui')['NSpace'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] diff --git a/package.json b/package.json index 6191f702..f7f4b00c 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@tiptap/starter-kit": "2.1.6", "@tiptap/vue-3": "2.0.3", "@types/figlet": "^1.5.8", + "@types/jsonpath": "^0.2.4", "@vicons/material": "^0.12.0", "@vicons/tabler": "^0.12.0", "@vueuse/core": "^10.3.0", @@ -65,8 +66,10 @@ "highlight.js": "^11.7.0", "iarna-toml-esm": "^3.0.5", "ibantools": "^4.3.3", + "jq-wasm": "^0.0.9", "js-base64": "^3.7.6", "json5": "^2.2.3", + "jsonpath": "^1.1.1", "jwt-decode": "^3.1.2", "libphonenumber-js": "^1.10.28", "lodash": "^4.17.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3044541a..df64d37d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ dependencies: '@types/figlet': specifier: ^1.5.8 version: 1.5.8 + '@types/jsonpath': + specifier: ^0.2.4 + version: 0.2.4 '@vicons/material': specifier: ^0.12.0 version: 0.12.0 @@ -95,12 +98,18 @@ dependencies: ibantools: specifier: ^4.3.3 version: 4.3.3 + jq-wasm: + specifier: ^0.0.9 + version: 0.0.9 js-base64: specifier: ^3.7.6 version: 3.7.7 json5: specifier: ^2.2.3 version: 2.2.3 + jsonpath: + specifier: ^1.1.1 + version: 1.1.1 jwt-decode: specifier: ^3.1.2 version: 3.1.2 @@ -2946,6 +2955,10 @@ packages: '@types/node': 18.15.11 dev: true + /@types/jsonpath@0.2.4: + resolution: {integrity: sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==} + dev: false + /@types/katex@0.16.5: resolution: {integrity: sha512-DD2Y3xMlTQvAnN6d8803xdgnOeYZ+HwMglb7/9YCf49J9RkJL53azf9qKa40MkEYhqVwxZ1GS2+VlShnz4Z1Bw==} dev: false @@ -3360,7 +3373,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.11.1(vue@3.3.4) + '@vueuse/shared': 11.0.3(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3993,19 +4006,19 @@ packages: - vue dev: false - /@vueuse/shared@10.11.1(vue@3.3.4): - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + /@vueuse/shared@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} dependencies: - vue-demi: 0.14.10(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} + /@vueuse/shared@11.0.3(vue@3.3.4): + resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} dependencies: - vue-demi: 0.14.5(vue@3.3.4) + vue-demi: 0.14.10(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -4802,7 +4815,6 @@ packages: /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true /deepmerge-ts@5.1.0: resolution: {integrity: sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==} @@ -5145,6 +5157,19 @@ packages: engines: {node: '>=12'} dev: false + /escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: false + /escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} @@ -5485,11 +5510,16 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /esprima@1.2.2: + resolution: {integrity: sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true - dev: true /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} @@ -5508,7 +5538,6 @@ packages: /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} - dev: true /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} @@ -5525,7 +5554,6 @@ packages: /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - dev: true /event-stream@3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} @@ -5595,7 +5623,6 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} @@ -6487,6 +6514,10 @@ packages: hasBin: true dev: true + /jq-wasm@0.0.9: + resolution: {integrity: sha512-qsfuch2xRjbM4VD5kkjlPciLA+bUaLR/IzaMyREulsiwP6nLkpEDNbyWA1XqV06Dx/EoJxvn2xAxZGP1LAmT0Q==} + dev: false + /js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} dev: false @@ -6625,6 +6656,14 @@ packages: graceful-fs: 4.2.11 dev: true + /jsonpath@1.1.1: + resolution: {integrity: sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==} + dependencies: + esprima: 1.2.2 + static-eval: 2.0.2 + underscore: 1.12.1 + dev: false + /jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} @@ -6667,6 +6706,14 @@ packages: engines: {node: '>=6'} dev: true + /levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: false + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -7191,6 +7238,18 @@ packages: is-wsl: 2.2.0 dev: true + /optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + dev: false + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -7482,6 +7541,11 @@ packages: source-map-js: 1.0.2 dev: true + /prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + dev: false + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -8152,7 +8216,6 @@ packages: /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true /source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} @@ -8213,6 +8276,12 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true + /static-eval@2.0.2: + resolution: {integrity: sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==} + dependencies: + escodegen: 1.14.3 + dev: false + /std-env@3.3.3: resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} dev: true @@ -8528,6 +8597,13 @@ packages: typescript: 5.2.2 dev: true + /type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -8655,6 +8731,10 @@ packages: mlly: 1.4.2 dev: true + /underscore@1.12.1: + resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} + dev: false + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: true @@ -9387,6 +9467,11 @@ packages: stackback: 0.0.2 dev: true + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: false + /workbox-background-sync@7.0.0: resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==} dependencies: diff --git a/src/tools/index.ts b/src/tools/index.ts index b4c161ef..8f0692e6 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -2,6 +2,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; import { tool as emailNormalizer } from './email-normalizer'; +import { tool as jqTester } from './jq-tester'; import { tool as asciiTextDrawer } from './ascii-text-drawer'; @@ -154,6 +155,7 @@ export const toolsByCategory: ToolCategory[] = [ xmlFormatter, yamlViewer, emailNormalizer, + jqTester, ], }, { diff --git a/src/tools/jq-tester/index.ts b/src/tools/jq-tester/index.ts new file mode 100644 index 00000000..af006ec9 --- /dev/null +++ b/src/tools/jq-tester/index.ts @@ -0,0 +1,12 @@ +import { Braces } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Jq/JSONPath Tester', + path: '/jq-tester', + description: 'Test jq/JSONPath expression against a JSON content', + keywords: ['jq', 'json', 'tester', 'jsonpath'], + component: () => import('./jq-tester.vue'), + icon: Braces, + createdAt: new Date('2024-08-15'), +}); diff --git a/src/tools/jq-tester/jq-tester.vue b/src/tools/jq-tester/jq-tester.vue new file mode 100644 index 00000000..8f44d826 --- /dev/null +++ b/src/tools/jq-tester/jq-tester.vue @@ -0,0 +1,83 @@ + + + From 4015507693601a7629de8876eb65539e348f13ed Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 27 Oct 2024 23:15:57 +0100 Subject: [PATCH 2/2] feat: JSONPath and JQ memo --- components.d.ts | 2 + src/tools/index.ts | 4 + src/tools/jq-memo/index.ts | 12 +++ src/tools/jq-memo/jq-memo.md | 89 +++++++++++++++++++++++ src/tools/jq-memo/jq-memo.vue | 32 ++++++++ src/tools/jq-tester/jq-tester.vue | 31 +++++--- src/tools/jsonpath-memo/index.ts | 12 +++ src/tools/jsonpath-memo/jsonpath-memo.md | 52 +++++++++++++ src/tools/jsonpath-memo/jsonpath-memo.vue | 32 ++++++++ 9 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 src/tools/jq-memo/index.ts create mode 100644 src/tools/jq-memo/jq-memo.md create mode 100644 src/tools/jq-memo/jq-memo.vue create mode 100644 src/tools/jsonpath-memo/index.ts create mode 100644 src/tools/jsonpath-memo/jsonpath-memo.md create mode 100644 src/tools/jsonpath-memo/jsonpath-memo.vue diff --git a/components.d.ts b/components.d.ts index bd29051c..225308cd 100644 --- a/components.d.ts +++ b/components.d.ts @@ -107,9 +107,11 @@ declare module '@vue/runtime-core' { Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default'] Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default'] Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default'] + JqMemo: typeof import('./src/tools/jq-memo/jq-memo.md')['default'] JqTester: typeof import('./src/tools/jq-tester/jq-tester.vue')['default'] JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default'] JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default'] + JsonpathMemo: typeof import('./src/tools/jsonpath-memo/jsonpath-memo.md')['default'] JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default'] JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default'] JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default'] diff --git a/src/tools/index.ts b/src/tools/index.ts index 8f0692e6..4e81e308 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -3,6 +3,8 @@ import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; import { tool as emailNormalizer } from './email-normalizer'; import { tool as jqTester } from './jq-tester'; +import { tool as jsonpathMemo } from './jsonpath-memo'; +import { tool as jqMemo } from './jq-memo'; import { tool as asciiTextDrawer } from './ascii-text-drawer'; @@ -156,6 +158,8 @@ export const toolsByCategory: ToolCategory[] = [ yamlViewer, emailNormalizer, jqTester, + jqMemo, + jsonpathMemo, ], }, { diff --git a/src/tools/jq-memo/index.ts b/src/tools/jq-memo/index.ts new file mode 100644 index 00000000..85d7e5c0 --- /dev/null +++ b/src/tools/jq-memo/index.ts @@ -0,0 +1,12 @@ +import { Brackets } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Jq Cheatsheet', + path: '/jq-memo', + description: 'JQ command cheatsheet', + keywords: ['jq', 'cheatsheet', 'memo'], + component: () => import('./jq-memo.vue'), + icon: Brackets, + createdAt: new Date('2024-08-15'), +}); diff --git a/src/tools/jq-memo/jq-memo.md b/src/tools/jq-memo/jq-memo.md new file mode 100644 index 00000000..c7e22cc6 --- /dev/null +++ b/src/tools/jq-memo/jq-memo.md @@ -0,0 +1,89 @@ +# Processing JSON using jq + +jq is useful to slice, filter, map and transform structured json data. + +## Installing jq + +### On Mac OS + +`brew install jq` + +### On AWS Linux + +Not available as yum install on our current AMI. It should be on the latest AMI though: https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/ + +Installing from the source proved to be tricky. + +## Useful arguments + +When running jq, the following arguments may become handy: + +| Argument | Description | +| ------ | :--------- | +| `--version`| Output the jq version and exit with zero. | +| `--sort-keys` | Output the fields of each object with the keys in sorted order.| + +## Basic concepts + +The syntax for jq is pretty coherent: + +| Syntax | Description | +| ------ | :--------- | +| , | Filters separated by a comma will produce multiple independent outputs| +| ? | Will ignores error if the type is unexpected | +| [] | Array construction | +| {} | Object construction | +| + | Concatenate or Add | +| - | Difference of sets or Substract | +| length | Size of selected element | +| | | Pipes are used to chain commands in a similar fashion than bash| + + +## Dealing with json objects + +| Description | Command | +| ------ | :--------- | +| Display all keys | `jq 'keys'` | +| Adds + 1 to all items | `jq 'map_values(.+1)'` | +| Delete a key| `jq 'del(.foo)'` | +| Convert an object to array | `to_entries | map([.key, .value])` | + +## Dealing with fields + +| Description | Command | +| ------ | :--------- | +| Concatenate two fields| `fieldNew=.field1+' '+.field2` | + + +## Dealing with json arrays + +### Slicing and Filtering + +| Description | Command | +| ------ | :--------- | +| All | `jq .[]` | +| First | `jq '.[0]'` | +| Range | `jq '.[2:4]'` | +| First 3 | `jq '.[:3]'` | +| Last 2 | `jq '.[-2:]'` | +| Before Last | `jq '.[-2]'`| +| Select array of int by value | `jq 'map(select(. >= 2))'` | +| Select array of objects by value| `jq '.[] | select(.id == "second")'` | +| Select by type | `jq '.[] | numbers'` with type been arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars | + +### Mapping and Transforming + +| Description | Command | +| ------ | :--------- | +| Add + 1 to all items | `jq 'map(.+1)'` | +| Delete 2 items| `jq 'del(.[1, 2])'` | +| Concatenate arrays | `jq 'add'` | +| Flatten an array | `jq 'flatten'` | +| Create a range of numbers | `jq '[range(2;4)]'` | +| Display the type of each item| `jq 'map(type)'` | +| Sort an array of basic type| `jq 'sort'` | +| Sort an array of objects | `jq 'sort_by(.foo)'` | +| Group by a key - opposite to flatten | `jq 'group_by(.foo)'` | +| Minimun value of an array| `jq 'min'` .See also min, max, min_by(path_exp), max_by(path_exp) | +| Remove duplicates| `jq 'unique'` or `jq 'unique_by(.foo)'` or `jq 'unique_by(length)'` | +| Reverse an array | `jq 'reverse'` | \ No newline at end of file diff --git a/src/tools/jq-memo/jq-memo.vue b/src/tools/jq-memo/jq-memo.vue new file mode 100644 index 00000000..ddbae0dd --- /dev/null +++ b/src/tools/jq-memo/jq-memo.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/tools/jq-tester/jq-tester.vue b/src/tools/jq-tester/jq-tester.vue index 8f44d826..2f6b4f52 100644 --- a/src/tools/jq-tester/jq-tester.vue +++ b/src/tools/jq-tester/jq-tester.vue @@ -54,16 +54,27 @@ const jsonValidation = useValidation({ mb-2 /> - - - - - +
+ + + + + +
+ +
+ + See jq Cheatsheet + + + See JSONPath Cheatsheet + +
import('./jsonpath-memo.vue'), + icon: Brackets, + createdAt: new Date('2024-08-15'), +}); diff --git a/src/tools/jsonpath-memo/jsonpath-memo.md b/src/tools/jsonpath-memo/jsonpath-memo.md new file mode 100644 index 00000000..62813b48 --- /dev/null +++ b/src/tools/jsonpath-memo/jsonpath-memo.md @@ -0,0 +1,52 @@ +## Syntax + +Depending on the client used JSONPath expressions do start with `$.` indicating the root element. +Some clients omit the leading `$.`. + +| Syntax | Description | +| ------ | :--------- | +| `$.store.book[0].title` | | +| `store.book[0].title` | With implicit `$.` | +| `$['store']['book'][0]['title']` | Alternative notation similar to scripting languages | + +## Tree Traversal + +| Syntax | Description | +| ------ | :--------- | +| `$.parentNode.childNode.field` | XPath: `/parentNode/childNode/@field` (content of "field" of all "childNode"s of "parentNode") | +| `$..anyChildNode` | XPath: `//anyChildNode` (all children at any depth named "anyChildNode") | +| `$.parentNode.*` | XPath: `/parentNode/*` (all children below) | + +## Array Access + +| Syntax | Description | +| ------ | :--------- | +| `$.myList[0]` | first element | +| `$.myList[-1]` | last element | +| `$.myList[2:3]` | range | +| `$.myList[0,4,5]` | selection | + +## Filtering + +| Syntax | Description | +| ------ | :--------- | +| `$.customer[?(@.car)]` | Only "customer"s that have attribute "car" | +| `$.customer[?(@.car == 'Ford Fiesta')]` | Only "customer"s with "Ford Fiesta"s | +| `$.customer[?(@.age > 18)]` | Only adults | + +## Complex Conditions + +| Syntax | Description | +| ------ | :--------- | +| `$.customer[?(@.age > 18 \|\| @.car == 'Ford Fiesta')]` | logical or | +| `$.customer[?(@.age < 18 && @.hobby == 'Biking' )]` | logical and | + +## Output Mapping + +| Syntax | Description | +| ------ | :--------- | +| `$.[].{Name:name, Age:age, Hobbies:details.hobbies}` | Mapping fields/nested fields to new set + +## Credits + +Original author: https://gist.github.com/mackoj/5786f8b95da0a82e8e003f444c4295bf \ No newline at end of file diff --git a/src/tools/jsonpath-memo/jsonpath-memo.vue b/src/tools/jsonpath-memo/jsonpath-memo.vue new file mode 100644 index 00000000..7ae49620 --- /dev/null +++ b/src/tools/jsonpath-memo/jsonpath-memo.vue @@ -0,0 +1,32 @@ + + + + +