From 4015507693601a7629de8876eb65539e348f13ed Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 27 Oct 2024 23:15:57 +0100 Subject: [PATCH] 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 @@ + + + + +