feat(json-prettify): sort keys
This commit is contained in:
		
							parent
							
								
									863c8d0f6a
								
							
						
					
					
						commit
						3b625fd473
					
				| @ -1,4 +1,15 @@ | |||||||
| <template> | <template> | ||||||
|  |   <div style="flex: 0 0 100%"> | ||||||
|  |     <n-space style="margin: 0 auto; max-width: 600px" justify="center"> | ||||||
|  |       <n-form-item label="Sort keys :" label-placement="left" label-width="100"> | ||||||
|  |         <n-switch v-model:value="sortKeys" /> | ||||||
|  |       </n-form-item> | ||||||
|  |       <n-form-item label="Indent size :" label-placement="left" label-width="100" :show-feedback="false"> | ||||||
|  |         <n-input-number v-model:value="indentSize" min="0" max="10" style="width: 100px" /> | ||||||
|  |       </n-form-item> | ||||||
|  |     </n-space> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|   <n-form-item |   <n-form-item | ||||||
|     label="Your raw json" |     label="Your raw json" | ||||||
|     :feedback="rawJsonValidation.message" |     :feedback="rawJsonValidation.message" | ||||||
| @ -25,13 +36,17 @@ | |||||||
| import TextareaCopyable from '@/components/TextareaCopyable.vue'; | import TextareaCopyable from '@/components/TextareaCopyable.vue'; | ||||||
| import { useValidation } from '@/composable/validation'; | import { useValidation } from '@/composable/validation'; | ||||||
| import { withDefaultOnError } from '@/utils/defaults'; | import { withDefaultOnError } from '@/utils/defaults'; | ||||||
| import JSON5 from 'json5'; |  | ||||||
| import { computed, ref } from 'vue'; | import { computed, ref } from 'vue'; | ||||||
|  | import JSON5 from 'json5'; | ||||||
|  | import { useStorage } from '@vueuse/core'; | ||||||
|  | import { formatJson } from './json.models'; | ||||||
| 
 | 
 | ||||||
| const inputElement = ref<HTMLElement>(); | const inputElement = ref<HTMLElement>(); | ||||||
| 
 | 
 | ||||||
| const rawJson = ref('{"hello": "world"}'); | const rawJson = useStorage('json-prettify:raw-json', '{"hello": "world", "foo": "bar"}'); | ||||||
| const cleanJson = computed(() => withDefaultOnError(() => JSON.stringify(JSON5.parse(rawJson.value), null, 3), '')); | const indentSize = useStorage('json-prettify:indent-size', 3); | ||||||
|  | const sortKeys = useStorage('json-prettify:sort-keys', true); | ||||||
|  | const cleanJson = computed(() => withDefaultOnError(() => formatJson({ rawJson, indentSize, sortKeys }), '')); | ||||||
| 
 | 
 | ||||||
| const rawJsonValidation = useValidation({ | const rawJsonValidation = useValidation({ | ||||||
|   source: rawJson, |   source: rawJson, | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/tools/json-viewer/json.models.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/tools/json-viewer/json.models.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | import { describe, expect, it } from 'vitest'; | ||||||
|  | import { sortObjectKeys } from './json.models'; | ||||||
|  | 
 | ||||||
|  | describe('json models', () => { | ||||||
|  |   describe('sortObjectKeys', () => { | ||||||
|  |     it('the object keys are recursively sorted alphabetically', () => { | ||||||
|  |       expect(JSON.stringify(sortObjectKeys({ b: 2, a: 1 }))).to.deep.equal(JSON.stringify({ a: 1, b: 2 })); | ||||||
|  |       // To unsure that this way of testing is working
 | ||||||
|  |       expect(JSON.stringify(sortObjectKeys({ b: 2, a: 1 }))).to.not.deep.equal(JSON.stringify({ b: 2, a: 1 })); | ||||||
|  | 
 | ||||||
|  |       expect(JSON.stringify(sortObjectKeys({ b: 2, a: 1, d: { j: 7, a: [{ z: 9, y: 8 }] }, c: 3 }))).to.deep.equal( | ||||||
|  |         JSON.stringify({ a: 1, b: 2, c: 3, d: { a: [{ y: 8, z: 9 }], j: 7 } }), | ||||||
|  |       ); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										35
									
								
								src/tools/json-viewer/json.models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/tools/json-viewer/json.models.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | import { get, type MaybeRef } from '@vueuse/core'; | ||||||
|  | import JSON5 from 'json5'; | ||||||
|  | 
 | ||||||
|  | export { sortObjectKeys, formatJson }; | ||||||
|  | 
 | ||||||
|  | function sortObjectKeys<T>(obj: T): T { | ||||||
|  |   if (typeof obj !== 'object' || obj === null) { | ||||||
|  |     return obj; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (Array.isArray(obj)) { | ||||||
|  |     return obj.map(sortObjectKeys) as T; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Object.keys(obj) | ||||||
|  |     .sort() | ||||||
|  |     .reduce((sortedObj, key) => { | ||||||
|  |       sortedObj[key] = sortObjectKeys((obj as Record<string, unknown>)[key]); | ||||||
|  |       return sortedObj; | ||||||
|  |     }, {} as Record<string, unknown>) as T; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function formatJson({ | ||||||
|  |   rawJson, | ||||||
|  |   sortKeys = true, | ||||||
|  |   indentSize = 3, | ||||||
|  | }: { | ||||||
|  |   rawJson: MaybeRef<string>; | ||||||
|  |   sortKeys?: MaybeRef<boolean>; | ||||||
|  |   indentSize?: MaybeRef<number>; | ||||||
|  | }) { | ||||||
|  |   const parsedObject = JSON5.parse(get(rawJson)); | ||||||
|  | 
 | ||||||
|  |   return JSON.stringify(get(sortKeys) ? sortObjectKeys(parsedObject) : parsedObject, null, get(indentSize)); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user