diff --git a/apps/server/package.json b/apps/server/package.json index c195bde985..3a03d15f8a 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -17,11 +17,11 @@ "lowdb": "^7.0.1", "multer": "^1.4.5-lts.1", "node-osc": "^9.0.2", - "node-xlsx": "^0.23.0", "ontime-utils": "workspace:*", "sanitize-filename": "^1.6.3", "steno": "^4.0.2", - "ws": "^8.13.0" + "ws": "^8.13.0", + "xlsx": "^0.18.5" }, "devDependencies": { "@types/cors": "^2.8.17", diff --git a/apps/server/src/api-data/excel/excel.service.ts b/apps/server/src/api-data/excel/excel.service.ts index 5123c820cb..ee13486901 100644 --- a/apps/server/src/api-data/excel/excel.service.ts +++ b/apps/server/src/api-data/excel/excel.service.ts @@ -8,13 +8,14 @@ import { ImportMap } from 'ontime-utils'; import { extname } from 'path'; import { existsSync } from 'fs'; -import xlsx from 'node-xlsx'; +import xlsx from 'xlsx'; +import type { WorkBook } from 'xlsx'; import { parseExcel } from '../../utils/parser.js'; import { parseRundown } from '../../utils/parserFunctions.js'; import { deleteFile } from '../../utils/parserUtils.js'; -let excelData: { name: string; data: unknown[][] }[] = []; +let excelData: WorkBook; export async function saveExcelFile(filePath: string) { if (!existsSync(filePath)) { @@ -23,24 +24,25 @@ export async function saveExcelFile(filePath: string) { if (extname(filePath) != '.xlsx') { throw new Error('Wrong file format'); } - excelData = xlsx.parse(filePath, { cellDates: true }); + excelData = xlsx.readFile(filePath, { cellDates: true, cellFormula: false }); await deleteFile(filePath); } -export function listWorksheets() { - return excelData.map((value) => value.name); +export function listWorksheets(): string[] { + return excelData.SheetNames; } export function generateRundownPreview(options: ImportMap): { rundown: OntimeRundown; customFields: CustomFields } { - const data = excelData.find(({ name }) => name.toLowerCase() === options.worksheet.toLowerCase())?.data; + const data = excelData.Sheets[options.worksheet]; if (!data) { throw new Error(`Could not find data to import, maybe the worksheet name is incorrect: ${options.worksheet}`); } - const dataFromExcel = parseExcel(data, options); + const arrayOfData: any[][] = xlsx.utils.sheet_to_json(data, { header: 1, blankrows: false, raw: false }); + const dataFromExcel = parseExcel(arrayOfData, options); // we run the parsed data through an extra step to ensure the objects shape const { rundown, customFields } = parseRundown(dataFromExcel); if (rundown.length === 0) { @@ -48,7 +50,7 @@ export function generateRundownPreview(options: ImportMap): { rundown: OntimeRun } // clear the data - excelData = []; + excelData = undefined; return { rundown, customFields }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6acde450e6..cd15b70571 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,30 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@types/node': + specifier: 20.14.10 + version: 20.14.10 + '@typescript-eslint/eslint-plugin': + specifier: 7.16.1 + version: 7.16.1 + '@typescript-eslint/parser': + specifier: 7.16.1 + version: 7.16.1 + eslint: + specifier: 8.56.0 + version: 8.56.0 + eslint-plugin-prettier: + specifier: 5.1.3 + version: 5.1.3 + prettier: + specifier: 3.3.1 + version: 3.3.1 + typescript: + specifier: 5.5.3 + version: 5.5.3 + importers: .: @@ -291,9 +315,6 @@ importers: node-osc: specifier: ^9.0.2 version: 9.0.2 - node-xlsx: - specifier: ^0.23.0 - version: 0.23.0 ontime-utils: specifier: workspace:* version: link:../../packages/utils @@ -306,6 +327,9 @@ importers: ws: specifier: ^8.13.0 version: 8.13.0 + xlsx: + specifier: ^0.18.5 + version: 0.18.5 devDependencies: '@types/cors': specifier: ^2.8.17 @@ -2358,6 +2382,7 @@ packages: abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} @@ -2371,10 +2396,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.1: - resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} - engines: {node: '>=0.4.0'} - acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -2384,15 +2405,9 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true + adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -2651,6 +2666,10 @@ packages: caniuse-lite@1.0.30001570: resolution: {integrity: sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==} + cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + chai@4.3.10: resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} engines: {node: '>=4'} @@ -2700,6 +2719,10 @@ packages: clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2974,6 +2997,7 @@ packages: domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -3033,10 +3057,6 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - entities@4.4.0: - resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} - engines: {node: '>=0.12'} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -3369,6 +3389,10 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + framer-motion@10.11.2: resolution: {integrity: sha512-IrwuC9regNOU99JoM/Z62CAMA3awGV6AcF7e3bcgXk/ZoNlGSt5aVq0J7UAwtLmCkwVlRvBkiMnvv2mZ1GW2pg==} peerDependencies: @@ -3487,10 +3511,12 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported glob@9.3.2: resolution: {integrity: sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==} @@ -4178,11 +4204,6 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - node-xlsx@0.23.0: - resolution: {integrity: sha512-r3KaSZSsSrK92rbPXnX/vDdxURmPPik0rjJ3A+Pybzpjyrk4G6WyGfj8JIz5dMMEpCmWVpmO4qoVPBxnpLv/8Q==} - engines: {node: '>=10.0.0'} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -4779,10 +4800,6 @@ packages: snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -4801,6 +4818,10 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -5315,10 +5336,18 @@ packages: engines: {node: '>=8'} hasBin: true + wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} + word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -5326,18 +5355,6 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.12.0: - resolution: {integrity: sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.13.0: resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} engines: {node: '>=10.0.0'} @@ -5350,9 +5367,8 @@ packages: utf-8-validate: optional: true - xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz: - resolution: {tarball: https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz} - version: 0.19.3 + xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} engines: {node: '>=0.8'} hasBin: true @@ -5427,33 +5443,6 @@ packages: react: optional: true -catalogs: - default: - '@types/node': - specifier: 20.14.10 - version: 20.14.10 - '@typescript-eslint/eslint-plugin': - specifier: 7.16.1 - version: 7.16.1 - '@typescript-eslint/parser': - specifier: 7.16.1 - version: 7.16.1 - eslint: - specifier: 8.56.0 - version: 8.56.0 - eslint-config-prettier: - specifier: 9.1.0 - version: 9.1.0 - eslint-plugin-prettier: - specifier: 5.1.3 - version: 5.1.3 - prettier: - specifier: 3.3.1 - version: 3.3.1 - typescript: - specifier: 5.5.3 - version: 5.5.3 - snapshots: 7zip-bin@5.2.0: {} @@ -7633,22 +7622,18 @@ snapshots: acorn-globals@7.0.1: dependencies: - acorn: 8.8.2 - acorn-walk: 8.3.1 + acorn: 8.11.2 + acorn-walk: 8.3.2 acorn-jsx@5.3.2(acorn@8.11.2): dependencies: acorn: 8.11.2 - acorn-walk@8.3.1: {} - acorn-walk@8.3.2: {} acorn@8.11.2: {} - acorn@8.8.1: {} - - acorn@8.8.2: {} + adler-32@1.3.1: {} agent-base@6.0.2: dependencies: @@ -8014,6 +7999,11 @@ snapshots: caniuse-lite@1.0.30001570: {} + cfb@1.2.2: + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + chai@4.3.10: dependencies: assertion-error: 1.1.0 @@ -8080,6 +8070,8 @@ snapshots: dependencies: mimic-response: 1.0.1 + codepage@1.15.0: {} + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -8449,8 +8441,6 @@ snapshots: dependencies: once: 1.4.0 - entities@4.4.0: {} - entities@4.5.0: {} env-paths@2.2.1: {} @@ -8953,6 +8943,8 @@ snapshots: forwarded@0.2.0: {} + frac@1.1.2: {} + framer-motion@10.11.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: tslib: 2.5.0 @@ -9509,7 +9501,7 @@ snapshots: jsdom@21.1.0: dependencies: abab: 2.0.6 - acorn: 8.8.1 + acorn: 8.11.2 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 @@ -9532,7 +9524,7 @@ snapshots: whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - ws: 8.12.0 + ws: 8.13.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -9809,10 +9801,6 @@ snapshots: node-releases@2.0.14: {} - node-xlsx@0.23.0: - dependencies: - xlsx: https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz - normalize-path@3.0.0: {} normalize-url@6.1.0: {} @@ -9931,7 +9919,7 @@ snapshots: parse5@7.1.2: dependencies: - entities: 4.4.0 + entities: 4.5.0 parseurl@1.3.3: {} @@ -10328,7 +10316,7 @@ snapshots: dependencies: chokidar: 3.5.3 immutable: 4.2.2 - source-map-js: 1.0.2 + source-map-js: 1.2.0 sax@1.3.0: {} @@ -10444,8 +10432,6 @@ snapshots: dot-case: 3.0.4 tslib: 2.6.2 - source-map-js@1.0.2: {} - source-map-js@1.2.0: {} source-map-support@0.5.21: @@ -10460,6 +10446,10 @@ snapshots: sprintf-js@1.1.3: optional: true + ssf@0.11.2: + dependencies: + frac: 1.1.2 + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -10969,8 +10959,12 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wmf@1.0.2: {} + word-wrap@1.2.3: {} + word@0.3.0: {} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -10979,11 +10973,17 @@ snapshots: wrappy@1.0.2: {} - ws@8.12.0: {} - ws@8.13.0: {} - xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz: {} + xlsx@0.18.5: + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 xml-name-validator@4.0.0: {}