parent
							
								
									87984e2081
								
							
						
					
					
						commit
						d02443a288
					
				| @ -41,8 +41,8 @@ | |||||||
|     "@tiptap/pm": "2.1.6", |     "@tiptap/pm": "2.1.6", | ||||||
|     "@tiptap/starter-kit": "2.1.6", |     "@tiptap/starter-kit": "2.1.6", | ||||||
|     "@tiptap/vue-3": "2.0.3", |     "@tiptap/vue-3": "2.0.3", | ||||||
|     "@types/markdown-it": "^13.0.7", |  | ||||||
|     "@types/figlet": "^1.5.8", |     "@types/figlet": "^1.5.8", | ||||||
|  |     "@types/markdown-it": "^13.0.7", | ||||||
|     "@vicons/material": "^0.12.0", |     "@vicons/material": "^0.12.0", | ||||||
|     "@vicons/tabler": "^0.12.0", |     "@vicons/tabler": "^0.12.0", | ||||||
|     "@vueuse/core": "^10.3.0", |     "@vueuse/core": "^10.3.0", | ||||||
| @ -62,6 +62,7 @@ | |||||||
|     "emojilib": "^3.0.10", |     "emojilib": "^3.0.10", | ||||||
|     "figlet": "^1.7.0", |     "figlet": "^1.7.0", | ||||||
|     "figue": "^1.2.0", |     "figue": "^1.2.0", | ||||||
|  |     "flatten-anything": "^4.0.1", | ||||||
|     "fuse.js": "^6.6.2", |     "fuse.js": "^6.6.2", | ||||||
|     "highlight.js": "^11.7.0", |     "highlight.js": "^11.7.0", | ||||||
|     "iarna-toml-esm": "^3.0.5", |     "iarna-toml-esm": "^3.0.5", | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										28
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @ -86,6 +86,9 @@ dependencies: | |||||||
|   figue: |   figue: | ||||||
|     specifier: ^1.2.0 |     specifier: ^1.2.0 | ||||||
|     version: 1.2.0 |     version: 1.2.0 | ||||||
|  |   flatten-anything: | ||||||
|  |     specifier: ^4.0.1 | ||||||
|  |     version: 4.0.1 | ||||||
|   fuse.js: |   fuse.js: | ||||||
|     specifier: ^6.6.2 |     specifier: ^6.6.2 | ||||||
|     version: 6.6.2 |     version: 6.6.2 | ||||||
| @ -5651,6 +5654,14 @@ packages: | |||||||
|     dependencies: |     dependencies: | ||||||
|       to-regex-range: 5.0.1 |       to-regex-range: 5.0.1 | ||||||
| 
 | 
 | ||||||
|  |   /filter-anything@4.0.2: | ||||||
|  |     resolution: {integrity: sha512-tNBpTytI180+uGpKu4dFupbkA7rmEl+ZFo27mSeR8Ov80rpMDBbmLORGTsCkCN8s50aOS79P0sg3YUKz3Tr/4Q==} | ||||||
|  |     engines: {node: '>=18'} | ||||||
|  |     dependencies: | ||||||
|  |       is-what: 5.0.2 | ||||||
|  |       ts-toolbelt: 9.6.0 | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /find-up@4.1.0: |   /find-up@4.1.0: | ||||||
|     resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} |     resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
| @ -5678,6 +5689,14 @@ packages: | |||||||
|     resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} |     resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /flatten-anything@4.0.1: | ||||||
|  |     resolution: {integrity: sha512-Wz5tXB7Sgm54LHOqgbqvFlhKxzBZxA+TAv8AE28wfGpqk6zYkNauIS/ierU4VmNRokgzG2KnxhVYaUCXP+oPCQ==} | ||||||
|  |     engines: {node: '>=18'} | ||||||
|  |     dependencies: | ||||||
|  |       filter-anything: 4.0.2 | ||||||
|  |       is-what: 5.0.2 | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /flex-js@1.0.5: |   /flex-js@1.0.5: | ||||||
|     resolution: {integrity: sha512-Z5uoLzOGtTB/nzaTVVBbwmxOHBzHovAGJHLXE1TUKsQuN1RRWMOWeA08J9RRKtAl9TH9tkaH6fpjA4sLf0DzQw==} |     resolution: {integrity: sha512-Z5uoLzOGtTB/nzaTVVBbwmxOHBzHovAGJHLXE1TUKsQuN1RRWMOWeA08J9RRKtAl9TH9tkaH6fpjA4sLf0DzQw==} | ||||||
|     dev: false |     dev: false | ||||||
| @ -6448,6 +6467,11 @@ packages: | |||||||
|     resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} |     resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /is-what@5.0.2: | ||||||
|  |     resolution: {integrity: sha512-vI7Ui0qzNQ2ClDZd0bC7uqRk3T1imbX5cZODmVlqqdqiwmSIUX3CNSiRgFjFMJ987sVCMSa7xZeEDtpJduPg4A==} | ||||||
|  |     engines: {node: '>=18'} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /is-wsl@2.2.0: |   /is-wsl@2.2.0: | ||||||
|     resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} |     resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
| @ -8548,6 +8572,10 @@ packages: | |||||||
|       typescript: 5.2.2 |       typescript: 5.2.2 | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /ts-toolbelt@9.6.0: | ||||||
|  |     resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} | ||||||
|  |     dev: false | ||||||
|  | 
 | ||||||
|   /tslib@1.14.1: |   /tslib@1.14.1: | ||||||
|     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} |     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} | ||||||
|     dev: true |     dev: true | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								src/tools/json-to-csv/flatten-anything.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/tools/json-to-csv/flatten-anything.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | declare module "flatten-anything" { | ||||||
|  |     export function flatten(objectOrArray: { | ||||||
|  |         [key in string]: any; | ||||||
|  |     }, untilDepth?: number): { | ||||||
|  |         [key in string]: any; | ||||||
|  |     }; | ||||||
|  | } | ||||||
| @ -3,6 +3,10 @@ import { convertArrayToCsv, getHeaders } from './json-to-csv.service'; | |||||||
| 
 | 
 | ||||||
| describe('json-to-csv service', () => { | describe('json-to-csv service', () => { | ||||||
|   describe('getHeaders', () => { |   describe('getHeaders', () => { | ||||||
|  |     it('extracts all the keys from the array of nested objects', () => { | ||||||
|  |       expect(getHeaders({ array: [{ a: { c: 1, d: 1 }, b: 2 }, { a: 3, c: 4 }] })).toEqual(['a.c', 'a.d', 'b', 'a', 'c']); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|     it('extracts all the keys from the array of objects', () => { |     it('extracts all the keys from the array of objects', () => { | ||||||
|       expect(getHeaders({ array: [{ a: 1, b: 2 }, { a: 3, c: 4 }] })).toEqual(['a', 'b', 'c']); |       expect(getHeaders({ array: [{ a: 1, b: 2 }, { a: 3, c: 4 }] })).toEqual(['a', 'b', 'c']); | ||||||
|     }); |     }); | ||||||
| @ -20,7 +24,7 @@ describe('json-to-csv service', () => { | |||||||
| 
 | 
 | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b |         "a,b | ||||||
|         1,2 |         1,2 | ||||||
|         3,4" |         3,4" | ||||||
| @ -33,7 +37,7 @@ describe('json-to-csv service', () => { | |||||||
|         { a: 3, c: 4 }, |         { a: 3, c: 4 }, | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b,c |         "a,b,c | ||||||
|         1,2, |         1,2, | ||||||
|         3,,4" |         3,,4" | ||||||
| @ -45,7 +49,7 @@ describe('json-to-csv service', () => { | |||||||
|         { a: null, b: 2 }, |         { a: null, b: 2 }, | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b |         "a,b | ||||||
|         null,2" |         null,2" | ||||||
|       `);
 |       `);
 | ||||||
| @ -57,7 +61,7 @@ describe('json-to-csv service', () => { | |||||||
|         { b: 3 }, |         { b: 3 }, | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b |         "a,b | ||||||
|         ,2 |         ,2 | ||||||
|         ,3" |         ,3" | ||||||
| @ -69,7 +73,7 @@ describe('json-to-csv service', () => { | |||||||
|         { a: 'hello, world', b: 2 }, |         { a: 'hello, world', b: 2 }, | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b |         "a,b | ||||||
|         \\"hello, world\\",2" |         \\"hello, world\\",2" | ||||||
|       `);
 |       `);
 | ||||||
| @ -80,10 +84,32 @@ describe('json-to-csv service', () => { | |||||||
|         { a: 'hello "world"', b: 2 }, |         { a: 'hello "world"', b: 2 }, | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       expect(convertArrayToCsv({ array })).toMatchInlineSnapshot(` |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|         "a,b |         "a,b | ||||||
|         hello \\\\\\"world\\\\\\",2" |         hello \\\\\\"world\\\\\\",2" | ||||||
|       `);
 |       `);
 | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |     it('converts an array of nested objects to a CSV string', () => { | ||||||
|  |       const array = [ | ||||||
|  |         { a: { c: 1, d: 1 }, b: 2 }, | ||||||
|  |         { a: 3, c: 4 }, | ||||||
|  |       ]; | ||||||
|  | 
 | ||||||
|  |       expect(convertArrayToCsv({ arrayOrObject: array })).toMatchInlineSnapshot(` | ||||||
|  |         "a.c,a.d,b,a,c | ||||||
|  |         1,1,2,, | ||||||
|  |         ,,,3,4" | ||||||
|  |       `);
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('converts an object to a CSV string', () => { | ||||||
|  |       const obj = { a: { c: 1, d: 1 }, b: 2 }; | ||||||
|  | 
 | ||||||
|  |       expect(convertArrayToCsv({ arrayOrObject: obj })).toMatchInlineSnapshot(` | ||||||
|  |         "a.c,a.d,b | ||||||
|  |         1,1,2" | ||||||
|  |       `);
 | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,9 +1,11 @@ | |||||||
|  | import { flatten } from 'flatten-anything'; | ||||||
|  | 
 | ||||||
| export { getHeaders, convertArrayToCsv }; | export { getHeaders, convertArrayToCsv }; | ||||||
| 
 | 
 | ||||||
| function getHeaders({ array }: { array: Record<string, unknown>[] }): string[] { | function getHeaders({ array }: { array: Record<string, unknown>[] }): string[] { | ||||||
|   const headers = new Set<string>(); |   const headers = new Set<string>(); | ||||||
| 
 | 
 | ||||||
|   array.forEach(item => Object.keys(item).forEach(key => headers.add(key))); |   array.forEach(item => Object.keys(flatten(item)).forEach(key => headers.add(key))); | ||||||
| 
 | 
 | ||||||
|   return Array.from(headers); |   return Array.from(headers); | ||||||
| } | } | ||||||
| @ -26,10 +28,12 @@ function serializeValue(value: unknown): string { | |||||||
|   return valueAsString; |   return valueAsString; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function convertArrayToCsv({ array }: { array: Record<string, unknown>[] }): string { | function convertArrayToCsv({ arrayOrObject }: { arrayOrObject: Record<string, unknown>[] | Record<string, unknown> }): string { | ||||||
|  |   const array = !Array.isArray(arrayOrObject) ? [arrayOrObject] : arrayOrObject; | ||||||
|  | 
 | ||||||
|   const headers = getHeaders({ array }); |   const headers = getHeaders({ array }); | ||||||
| 
 | 
 | ||||||
|   const rows = array.map(item => headers.map(header => serializeValue(item[header]))); |   const rows = array.map(item => headers.map(header => serializeValue(flatten(item)[header]))); | ||||||
| 
 | 
 | ||||||
|   return [headers.join(','), ...rows].join('\n'); |   return [headers.join(','), ...rows].join('\n'); | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ function transformer(value: string) { | |||||||
|     if (value === '') { |     if (value === '') { | ||||||
|       return ''; |       return ''; | ||||||
|     } |     } | ||||||
|     return convertArrayToCsv({ array: JSON5.parse(value) }); |     return convertArrayToCsv({ arrayOrObject: JSON5.parse(value) }); | ||||||
|   }, ''); |   }, ''); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user