Merge 8545fc6fa5 into 63fbd3b45c
				
					
				
			This commit is contained in:
		
						commit
						6759a97ec7
					
				
							
								
								
									
										9
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -109,6 +109,7 @@ declare module '@vue/runtime-core' { | |||||||
|     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'] | ||||||
|     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'] | ||||||
|  |     JsonSizeAnalyzer: typeof import('./src/tools/json-size-analyzer/json-size-analyzer.vue')['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'] | ||||||
| @ -138,11 +139,15 @@ declare module '@vue/runtime-core' { | |||||||
|     NH1: typeof import('naive-ui')['NH1'] |     NH1: typeof import('naive-ui')['NH1'] | ||||||
|     NH3: typeof import('naive-ui')['NH3'] |     NH3: typeof import('naive-ui')['NH3'] | ||||||
|     NIcon: typeof import('naive-ui')['NIcon'] |     NIcon: typeof import('naive-ui')['NIcon'] | ||||||
|  |     NInput: typeof import('naive-ui')['NInput'] | ||||||
|  |     NInputNumber: typeof import('naive-ui')['NInputNumber'] | ||||||
|     NLayout: typeof import('naive-ui')['NLayout'] |     NLayout: typeof import('naive-ui')['NLayout'] | ||||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] |     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||||
|     NMenu: typeof import('naive-ui')['NMenu'] |     NMenu: typeof import('naive-ui')['NMenu'] | ||||||
|     NSpace: typeof import('naive-ui')['NSpace'] |     NScrollbar: typeof import('naive-ui')['NScrollbar'] | ||||||
|     NTable: typeof import('naive-ui')['NTable'] |     NSlider: typeof import('naive-ui')['NSlider'] | ||||||
|  |     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||||
|  |     NTree: typeof import('naive-ui')['NTree'] | ||||||
|     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] |     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'] |     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'] |     PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] | ||||||
|  | |||||||
| @ -70,6 +70,7 @@ | |||||||
|     "iarna-toml-esm": "^3.0.5", |     "iarna-toml-esm": "^3.0.5", | ||||||
|     "ibantools": "^4.3.3", |     "ibantools": "^4.3.3", | ||||||
|     "js-base64": "^3.7.6", |     "js-base64": "^3.7.6", | ||||||
|  |     "json-analyzer": "^1.2.2", | ||||||
|     "json5": "^2.2.3", |     "json5": "^2.2.3", | ||||||
|     "jwt-decode": "^3.1.2", |     "jwt-decode": "^3.1.2", | ||||||
|     "libphonenumber-js": "^1.10.28", |     "libphonenumber-js": "^1.10.28", | ||||||
|  | |||||||
							
								
								
									
										59
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										59
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @ -107,6 +107,9 @@ dependencies: | |||||||
|   js-base64: |   js-base64: | ||||||
|     specifier: ^3.7.6 |     specifier: ^3.7.6 | ||||||
|     version: 3.7.7 |     version: 3.7.7 | ||||||
|  |   json-analyzer: | ||||||
|  |     specifier: ^1.2.2 | ||||||
|  |     version: 1.2.2 | ||||||
|   json5: |   json5: | ||||||
|     specifier: ^2.2.3 |     specifier: ^2.2.3 | ||||||
|     version: 2.2.3 |     version: 2.2.3 | ||||||
| @ -3412,7 +3415,7 @@ packages: | |||||||
|     dependencies: |     dependencies: | ||||||
|       '@unhead/dom': 0.5.1 |       '@unhead/dom': 0.5.1 | ||||||
|       '@unhead/schema': 0.5.1 |       '@unhead/schema': 0.5.1 | ||||||
|       '@vueuse/shared': 11.0.3(vue@3.3.4) |       '@vueuse/shared': 11.1.0(vue@3.3.4) | ||||||
|       unhead: 0.5.1 |       unhead: 0.5.1 | ||||||
|       vue: 3.3.4 |       vue: 3.3.4 | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
| @ -4054,8 +4057,8 @@ packages: | |||||||
|       - vue |       - vue | ||||||
|     dev: false |     dev: false | ||||||
| 
 | 
 | ||||||
|   /@vueuse/shared@11.0.3(vue@3.3.4): |   /@vueuse/shared@11.1.0(vue@3.3.4): | ||||||
|     resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} |     resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==} | ||||||
|     dependencies: |     dependencies: | ||||||
|       vue-demi: 0.14.10(vue@3.3.4) |       vue-demi: 0.14.10(vue@3.3.4) | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
| @ -4581,6 +4584,11 @@ packages: | |||||||
|     resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} |     resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /colors@1.4.0: | ||||||
|  |     resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} | ||||||
|  |     engines: {node: '>=0.1.90'} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /combined-stream@1.0.8: |   /combined-stream@1.0.8: | ||||||
|     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} |     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} | ||||||
|     engines: {node: '>= 0.8'} |     engines: {node: '>= 0.8'} | ||||||
| @ -6636,6 +6644,21 @@ packages: | |||||||
|     hasBin: true |     hasBin: true | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /json-analyzer@1.2.2: | ||||||
|  |     resolution: {integrity: sha512-3xWTxyIggxOYIPT9NkucQPxlOBPJY14/ifely3eCtifE5pAxJXl/jUmSDwq+fLVhHIIj9MIJ6Bv7u3ItChG8vQ==} | ||||||
|  |     engines: {node: '>=8.0.0'} | ||||||
|  |     hasBin: true | ||||||
|  |     dependencies: | ||||||
|  |       commander: 2.20.3 | ||||||
|  |       lodash.flowright: 3.5.0 | ||||||
|  |       lodash.get: 4.4.2 | ||||||
|  |       lodash.isobject: 3.0.2 | ||||||
|  |       pako: 1.0.11 | ||||||
|  |       pretty-bytes: 5.6.0 | ||||||
|  |       prettyjson: 1.2.5 | ||||||
|  |       utf8-length: 0.0.1 | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /json-parse-even-better-errors@2.3.1: |   /json-parse-even-better-errors@2.3.1: | ||||||
|     resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} |     resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} | ||||||
|     dev: true |     dev: true | ||||||
| @ -6775,6 +6798,18 @@ packages: | |||||||
|     resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} |     resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /lodash.flowright@3.5.0: | ||||||
|  |     resolution: {integrity: sha512-YxTYuodkvyINbDInmFcGGvkQwoAuoGUYosqstRTr5eq63GQt7WQ2xFU0wG1UfdbKYPwevd3zWDd6ybEE2g6qvA==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|  |   /lodash.get@4.4.2: | ||||||
|  |     resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|  |   /lodash.isobject@3.0.2: | ||||||
|  |     resolution: {integrity: sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /lodash.merge@4.6.2: |   /lodash.merge@4.6.2: | ||||||
|     resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} |     resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} | ||||||
|     dev: true |     dev: true | ||||||
| @ -7022,7 +7057,6 @@ packages: | |||||||
| 
 | 
 | ||||||
|   /minimist@1.2.8: |   /minimist@1.2.8: | ||||||
|     resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} |     resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} | ||||||
|     dev: true |  | ||||||
| 
 | 
 | ||||||
|   /mlly@1.4.0: |   /mlly@1.4.0: | ||||||
|     resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} |     resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} | ||||||
| @ -7341,6 +7375,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} |     resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} | ||||||
|     engines: {node: '>=6'} |     engines: {node: '>=6'} | ||||||
| 
 | 
 | ||||||
|  |   /pako@1.0.11: | ||||||
|  |     resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /param-case@2.1.1: |   /param-case@2.1.1: | ||||||
|     resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} |     resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} | ||||||
|     dependencies: |     dependencies: | ||||||
| @ -7573,7 +7611,6 @@ packages: | |||||||
|   /pretty-bytes@5.6.0: |   /pretty-bytes@5.6.0: | ||||||
|     resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} |     resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} | ||||||
|     engines: {node: '>=6'} |     engines: {node: '>=6'} | ||||||
|     dev: true |  | ||||||
| 
 | 
 | ||||||
|   /pretty-bytes@6.1.0: |   /pretty-bytes@6.1.0: | ||||||
|     resolution: {integrity: sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==} |     resolution: {integrity: sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==} | ||||||
| @ -7589,6 +7626,14 @@ packages: | |||||||
|       react-is: 18.2.0 |       react-is: 18.2.0 | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /prettyjson@1.2.5: | ||||||
|  |     resolution: {integrity: sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==} | ||||||
|  |     hasBin: true | ||||||
|  |     dependencies: | ||||||
|  |       colors: 1.4.0 | ||||||
|  |       minimist: 1.2.8 | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /prosemirror-changeset@2.2.1: |   /prosemirror-changeset@2.2.1: | ||||||
|     resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==} |     resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==} | ||||||
|     dependencies: |     dependencies: | ||||||
| @ -9048,6 +9093,10 @@ packages: | |||||||
|       requires-port: 1.0.0 |       requires-port: 1.0.0 | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /utf8-length@0.0.1: | ||||||
|  |     resolution: {integrity: sha512-j/XH2ftofBiobnyApxlN/J6j/ixwT89WEjDcjT66d2i0+GIn9RZfzt8lpEXXE4jUe4NsjBSUq70kS2euQ4nnMw==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /util-deprecate@1.0.2: |   /util-deprecate@1.0.2: | ||||||
|     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} |     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} | ||||||
|     dev: true |     dev: true | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; | |||||||
| import { tool as base64StringConverter } from './base64-string-converter'; | 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 jsonSizeAnalyzer } from './json-size-analyzer'; | ||||||
| 
 | 
 | ||||||
| import { tool as asciiTextDrawer } from './ascii-text-drawer'; | import { tool as asciiTextDrawer } from './ascii-text-drawer'; | ||||||
| 
 | 
 | ||||||
| @ -151,6 +152,7 @@ export const toolsByCategory: ToolCategory[] = [ | |||||||
|       crontabGenerator, |       crontabGenerator, | ||||||
|       jsonViewer, |       jsonViewer, | ||||||
|       jsonMinify, |       jsonMinify, | ||||||
|  |       jsonSizeAnalyzer, | ||||||
|       jsonToCsv, |       jsonToCsv, | ||||||
|       sqlPrettify, |       sqlPrettify, | ||||||
|       chmodCalculator, |       chmodCalculator, | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/tools/json-size-analyzer/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/json-size-analyzer/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | import { FileAnalytics } from '@vicons/tabler'; | ||||||
|  | import { defineTool } from '../tool'; | ||||||
|  | 
 | ||||||
|  | export const tool = defineTool({ | ||||||
|  |   name: 'Json Size Analyzer', | ||||||
|  |   path: '/json-size-analyzer', | ||||||
|  |   description: 'Measure JSON nodes relative weights', | ||||||
|  |   keywords: ['json', 'size', 'analyzer'], | ||||||
|  |   component: () => import('./json-size-analyzer.vue'), | ||||||
|  |   icon: FileAnalytics, | ||||||
|  |   createdAt: new Date('2024-07-14'), | ||||||
|  | }); | ||||||
							
								
								
									
										13
									
								
								src/tools/json-size-analyzer/json-analyzer.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/tools/json-size-analyzer/json-analyzer.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | declare module 'json-analyzer' { | ||||||
|  |     export default function analyze({ | ||||||
|  |         json, | ||||||
|  |         verbose, | ||||||
|  |         maxDepth, | ||||||
|  |         target, | ||||||
|  |       }: { | ||||||
|  |         json: any, | ||||||
|  |         verbose: boolean, | ||||||
|  |         maxDepth: number, | ||||||
|  |         target: string, | ||||||
|  |       }); | ||||||
|  | } | ||||||
							
								
								
									
										113
									
								
								src/tools/json-size-analyzer/json-size-analyzer.service.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/tools/json-size-analyzer/json-size-analyzer.service.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,113 @@ | |||||||
|  | import { describe, expect, it } from 'vitest'; | ||||||
|  | import { getJsonUsageTreeNodes } from './json-size-analyzer.service'; | ||||||
|  | 
 | ||||||
|  | describe('json-size-analyzer', () => { | ||||||
|  |   describe('getJsonUsageTreeNodes', () => { | ||||||
|  |     it('return correct tree nodes structures', () => { | ||||||
|  |       expect(getJsonUsageTreeNodes([{ a: [1, 2, 3] }, { b: 'a' }])).to.deep.eq({ | ||||||
|  |         children: [ | ||||||
|  |           { | ||||||
|  |             children: [ | ||||||
|  |               { | ||||||
|  |                 children: [ | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.[0].a.[0]', | ||||||
|  |                     label: '$.[0].a.[0]: 1 B(26 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.[0].a.[1]', | ||||||
|  |                     label: '$.[0].a.[1]: 1 B(24 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.[0].a.[2]', | ||||||
|  |                     label: '$.[0].a.[2]: 1 B(25 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                 ], | ||||||
|  |                 key: '$.[0].a', | ||||||
|  |                 label: '$.[0].a: 7 B(35 B gzip) ; 28.000% of parent ; biggest child node: \'0\'', | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |             key: '$.[0]', | ||||||
|  |             label: '$.[0]: 13 B(43 B gzip) ; 52.000% of parent ; biggest child node: \'a\'', | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             children: [ | ||||||
|  |               { | ||||||
|  |                 children: [], | ||||||
|  |                 key: '$.[1].b', | ||||||
|  |                 label: '$.[1].b: 1 B(25 B gzip)', | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |             key: '$.[1]', | ||||||
|  |             label: '$.[1]: 9 B(34 B gzip) ; 36.000% of parent ; biggest child node: \'b\'', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |         key: '$', | ||||||
|  |         label: '$: 25 B(61 B gzip) ; 100.00% of parent ; biggest child node: \'0\'', | ||||||
|  |       }); | ||||||
|  |       expect(getJsonUsageTreeNodes({ a: { b: [1, 2, 3], c: 12 } })).to.deep.eq({ | ||||||
|  |         children: [ | ||||||
|  |           { | ||||||
|  |             children: [ | ||||||
|  |               { | ||||||
|  |                 children: [ | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.a.b.[0]', | ||||||
|  |                     label: '$.a.b.[0]: 1 B(26 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.a.b.[1]', | ||||||
|  |                     label: '$.a.b.[1]: 1 B(24 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                   { | ||||||
|  |                     children: [], | ||||||
|  |                     key: '$.a.b.[2]', | ||||||
|  |                     label: '$.a.b.[2]: 1 B(25 B gzip)', | ||||||
|  |                   }, | ||||||
|  |                 ], | ||||||
|  |                 key: '$.a.b', | ||||||
|  |                 label: '$.a.b: 7 B(35 B gzip) ; 26.923% of parent ; biggest child node: \'0\'', | ||||||
|  |               }, | ||||||
|  |               { | ||||||
|  |                 children: [], | ||||||
|  |                 key: '$.a.c', | ||||||
|  |                 label: '$.a.c: 2 B(24 B gzip)', | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |             key: '$.a', | ||||||
|  |             label: '$.a: 20 B(50 B gzip) ; 76.923% of parent ; biggest child node: \'b\'', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |         key: '$', | ||||||
|  |         label: '$: 26 B(63 B gzip) ; 100.00% of parent ; biggest child node: \'a\'', | ||||||
|  |       }); | ||||||
|  |       expect(getJsonUsageTreeNodes({ a: { b: 'azerty', c: 'ueop' } })).to.deep.eq({ | ||||||
|  |         children: [ | ||||||
|  |           { | ||||||
|  |             children: [ | ||||||
|  |               { | ||||||
|  |                 children: [], | ||||||
|  |                 key: '$.a.b', | ||||||
|  |                 label: '$.a.b: 6 B(30 B gzip)', | ||||||
|  |               }, | ||||||
|  |               { | ||||||
|  |                 children: [], | ||||||
|  |                 key: '$.a.c', | ||||||
|  |                 label: '$.a.c: 4 B(29 B gzip)', | ||||||
|  |               }, | ||||||
|  |             ], | ||||||
|  |             key: '$.a', | ||||||
|  |             label: '$.a: 25 B(51 B gzip) ; 80.645% of parent ; biggest child node: \'b\'', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |         key: '$', | ||||||
|  |         label: '$: 31 B(61 B gzip) ; 100.00% of parent ; biggest child node: \'a\'', | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										51
									
								
								src/tools/json-size-analyzer/json-size-analyzer.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/tools/json-size-analyzer/json-size-analyzer.service.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | import jsonAnalyzer from 'json-analyzer'; | ||||||
|  | 
 | ||||||
|  | export interface Meta { | ||||||
|  |   __meta__: { | ||||||
|  |     size?: { | ||||||
|  |       value: number | ||||||
|  |       raw: string | ||||||
|  |       gzip: string | ||||||
|  |     } | ||||||
|  |     number_of_childs?: number | ||||||
|  |     parent_relative_percentage?: string | ||||||
|  |     biggest_node_child: string | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | export type AnalysisNode = { | ||||||
|  |   [key: string]: object & Meta | ||||||
|  | } & Meta; | ||||||
|  | 
 | ||||||
|  | export type TreeNode = { | ||||||
|  |   key: string | ||||||
|  |   label: string | ||||||
|  |   children: Array<TreeNode> | ||||||
|  | } & Record<string, unknown>; | ||||||
|  | 
 | ||||||
|  | function getTreeNodes(obj: AnalysisNode, parentName: string): TreeNode { | ||||||
|  |   const childNodes = Object.entries(obj) | ||||||
|  |     .filter(([key, v]) => key !== '__meta__' && typeof v === 'object') | ||||||
|  |     .map(([k, v]) => ({ | ||||||
|  |       key: (Number.isNaN(Number.parseInt(k, 10)) ? `.${k}` : `.[${k}]`), | ||||||
|  |       value: v as AnalysisNode, | ||||||
|  |     })); | ||||||
|  |   const biggest_child_node = obj.__meta__.biggest_node_child ? ` ; biggest child node: '${obj.__meta__.biggest_node_child}'` : ''; | ||||||
|  |   const parent_relative_percentage = obj.__meta__.parent_relative_percentage ? ` ; ${obj.__meta__.parent_relative_percentage} of parent` : ''; | ||||||
|  |   return { | ||||||
|  |     key: parentName, | ||||||
|  |     label: obj.__meta__ | ||||||
|  |       ? `${parentName}: ${obj.__meta__.size?.raw}(${obj.__meta__.size?.gzip} gzip)${parent_relative_percentage}${biggest_child_node}` | ||||||
|  |       : parentName, | ||||||
|  |     children: childNodes.map(childNode => getTreeNodes(childNode.value, parentName + childNode.key)), | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function getJsonUsageTreeNodes(jsonObj: any, maxDepth: number = 100, targetNode: string = ''): TreeNode { | ||||||
|  |   const analysis = jsonAnalyzer({ | ||||||
|  |     json: jsonObj, | ||||||
|  |     verbose: true, | ||||||
|  |     maxDepth, | ||||||
|  |     target: targetNode, | ||||||
|  |   }); | ||||||
|  |   return getTreeNodes(analysis, '$'); | ||||||
|  | } | ||||||
							
								
								
									
										68
									
								
								src/tools/json-size-analyzer/json-size-analyzer.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/tools/json-size-analyzer/json-size-analyzer.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import JSON5 from 'json5'; | ||||||
|  | import { getJsonUsageTreeNodes } from './json-size-analyzer.service'; | ||||||
|  | import { useValidation } from '@/composable/validation'; | ||||||
|  | 
 | ||||||
|  | const json = ref('{"a": 1, "b": [1,2,3]}'); | ||||||
|  | const maxDepth = ref(100); | ||||||
|  | const target = ref(''); | ||||||
|  | 
 | ||||||
|  | const jsonSizes = computed(() => { | ||||||
|  |   const jsonObj = JSON5.parse(json.value); | ||||||
|  |   if (!jsonObj) { | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  |   return [getJsonUsageTreeNodes(jsonObj, maxDepth.value - 1, target.value)]; | ||||||
|  | }); | ||||||
|  | const searchInAnalysis = ref(''); | ||||||
|  | 
 | ||||||
|  | const jsonValidation = useValidation({ | ||||||
|  |   source: json, | ||||||
|  |   rules: [ | ||||||
|  |     { | ||||||
|  |       validator: (v) => { | ||||||
|  |         return JSON5.parse(v); | ||||||
|  |       }, | ||||||
|  |       message: 'Provided JSON is not valid.', | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div style="max-width: 600px;"> | ||||||
|  |     <c-card title="Input" mb-2> | ||||||
|  |       <c-input-text | ||||||
|  |         v-model:value="json" | ||||||
|  |         label="JSON" | ||||||
|  |         multiline | ||||||
|  |         placeholder="Put your JSON data here..." | ||||||
|  |         rows="5" | ||||||
|  |         :validation="jsonValidation" | ||||||
|  |         mb-2 | ||||||
|  |       /> | ||||||
|  | 
 | ||||||
|  |       <n-form-item label="Max Depth:" label-placement="left"> | ||||||
|  |         <n-input-number v-model:value="maxDepth" :min="0" w-full /> | ||||||
|  |       </n-form-item> | ||||||
|  | 
 | ||||||
|  |       <c-input-text | ||||||
|  |         v-model:value="target" | ||||||
|  |         label="Target Node" | ||||||
|  |         placeholder="Where to start the analyze (ie, a[0].b.c)" | ||||||
|  |         mb-2 | ||||||
|  |       /> | ||||||
|  |     </c-card> | ||||||
|  | 
 | ||||||
|  |     <c-card v-if="jsonSizes" title="Analysis"> | ||||||
|  |       <n-input v-model:value="searchInAnalysis" placeholder="Search in result" /> | ||||||
|  |       <n-tree | ||||||
|  |         :show-irrelevant-nodes="false" | ||||||
|  |         :pattern="searchInAnalysis" | ||||||
|  |         :default-expand-all="true" | ||||||
|  |         :data="jsonSizes" | ||||||
|  |         block-line | ||||||
|  |       /> | ||||||
|  |     </c-card> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user