feat: JSONPath and JQ memo
This commit is contained in:
		
							parent
							
								
									0d9f6aa01b
								
							
						
					
					
						commit
						4015507693
					
				
							
								
								
									
										2
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -107,9 +107,11 @@ declare module '@vue/runtime-core' { | |||||||
|     Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default'] |     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'] |     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'] |     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'] |     JqTester: typeof import('./src/tools/jq-tester/jq-tester.vue')['default'] | ||||||
|     JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default'] |     JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default'] | ||||||
|     JsonMinify: typeof import('./src/tools/json-minify/json-minify.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'] |     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'] |     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'] |     JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default'] | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ import { tool as base64StringConverter } from './base64-string-converter'; | |||||||
| import { tool as basicAuthGenerator } from './basic-auth-generator'; | import { tool as basicAuthGenerator } from './basic-auth-generator'; | ||||||
| import { tool as emailNormalizer } from './email-normalizer'; | import { tool as emailNormalizer } from './email-normalizer'; | ||||||
| import { tool as jqTester } from './jq-tester'; | 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'; | import { tool as asciiTextDrawer } from './ascii-text-drawer'; | ||||||
| 
 | 
 | ||||||
| @ -156,6 +158,8 @@ export const toolsByCategory: ToolCategory[] = [ | |||||||
|       yamlViewer, |       yamlViewer, | ||||||
|       emailNormalizer, |       emailNormalizer, | ||||||
|       jqTester, |       jqTester, | ||||||
|  |       jqMemo, | ||||||
|  |       jsonpathMemo, | ||||||
|     ], |     ], | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/tools/jq-memo/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/jq-memo/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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'), | ||||||
|  | }); | ||||||
							
								
								
									
										89
									
								
								src/tools/jq-memo/jq-memo.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/tools/jq-memo/jq-memo.md
									
									
									
									
									
										Normal file
									
								
							| @ -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'` | | ||||||
							
								
								
									
										32
									
								
								src/tools/jq-memo/jq-memo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/tools/jq-memo/jq-memo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useThemeVars } from 'naive-ui'; | ||||||
|  | import Memo from './jq-memo.md'; | ||||||
|  | 
 | ||||||
|  | const themeVars = useThemeVars(); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <Memo style="overflow-x: auto;" /> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | ::v-deep(pre) { | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 15px 22px; | ||||||
|  |   background-color: v-bind('themeVars.cardColor'); | ||||||
|  |   border-radius: 4px; | ||||||
|  |   overflow: auto; | ||||||
|  | } | ||||||
|  | ::v-deep(table) { | ||||||
|  |   border-collapse: collapse; | ||||||
|  | } | ||||||
|  | ::v-deep(table), ::v-deep(td), ::v-deep(th) { | ||||||
|  |   border: 1px solid v-bind('themeVars.textColor1'); | ||||||
|  |   padding: 5px; | ||||||
|  | } | ||||||
|  | ::v-deep(a) { | ||||||
|  |   color: v-bind('themeVars.textColor1'); | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -54,6 +54,7 @@ const jsonValidation = useValidation({ | |||||||
|         mb-2 |         mb-2 | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|  |       <div mb-2 flex justify-center> | ||||||
|         <n-radio-group v-model:value="jqtype" name="jqtype"> |         <n-radio-group v-model:value="jqtype" name="jqtype"> | ||||||
|           <n-space> |           <n-space> | ||||||
|             <n-radio |             <n-radio | ||||||
| @ -64,6 +65,16 @@ const jsonValidation = useValidation({ | |||||||
|             /> |             /> | ||||||
|           </n-space> |           </n-space> | ||||||
|         </n-radio-group> |         </n-radio-group> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <div mb-2 flex justify-center> | ||||||
|  |         <router-link v-if="jqtype === 'jq'" target="_blank" to="/jq-memo" mb-1 mt-1> | ||||||
|  |           See <code>jq</code> Cheatsheet | ||||||
|  |         </router-link> | ||||||
|  |         <router-link v-if="jqtype === 'jsonpath'" target="_blank" to="/jsonpath-memo" mb-1 mt-1> | ||||||
|  |           See JSONPath Cheatsheet | ||||||
|  |         </router-link> | ||||||
|  |       </div> | ||||||
| 
 | 
 | ||||||
|       <c-input-text |       <c-input-text | ||||||
|         v-model:value="json" |         v-model:value="json" | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/tools/jsonpath-memo/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/jsonpath-memo/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | import { Brackets } from '@vicons/tabler'; | ||||||
|  | import { defineTool } from '../tool'; | ||||||
|  | 
 | ||||||
|  | export const tool = defineTool({ | ||||||
|  |   name: 'JSONPath Syntax Cheatsheet', | ||||||
|  |   path: '/jsonpath-memo', | ||||||
|  |   description: 'JSONPath Syntax Cheatsheet', | ||||||
|  |   keywords: ['jsonpath', 'cheatsheet', 'memo'], | ||||||
|  |   component: () => import('./jsonpath-memo.vue'), | ||||||
|  |   icon: Brackets, | ||||||
|  |   createdAt: new Date('2024-08-15'), | ||||||
|  | }); | ||||||
							
								
								
									
										52
									
								
								src/tools/jsonpath-memo/jsonpath-memo.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/tools/jsonpath-memo/jsonpath-memo.md
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										32
									
								
								src/tools/jsonpath-memo/jsonpath-memo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/tools/jsonpath-memo/jsonpath-memo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useThemeVars } from 'naive-ui'; | ||||||
|  | import Memo from './jsonpath-memo.md'; | ||||||
|  | 
 | ||||||
|  | const themeVars = useThemeVars(); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div max-w-600px> | ||||||
|  |     <Memo style="overflow-x: auto;" /> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | ::v-deep(pre) { | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 15px 22px; | ||||||
|  |   background-color: v-bind('themeVars.cardColor'); | ||||||
|  |   border-radius: 4px; | ||||||
|  |   overflow: auto; | ||||||
|  | } | ||||||
|  | ::v-deep(table) { | ||||||
|  |   border-collapse: collapse; | ||||||
|  | } | ||||||
|  | ::v-deep(table), ::v-deep(td), ::v-deep(th) { | ||||||
|  |   border: 1px solid v-bind('themeVars.textColor1'); | ||||||
|  |   padding: 5px; | ||||||
|  | } | ||||||
|  | ::v-deep(a) { | ||||||
|  |   color: v-bind('themeVars.textColor1'); | ||||||
|  | } | ||||||
|  | </style> | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user