diff --git a/libs/execution/src/lib/debugging/debug-log-visitor.ts b/libs/execution/src/lib/debugging/debug-log-visitor.ts index 44141b16d..862cbd772 100644 --- a/libs/execution/src/lib/debugging/debug-log-visitor.ts +++ b/libs/execution/src/lib/debugging/debug-log-visitor.ts @@ -5,6 +5,7 @@ import { internalValueToString } from '@jvalue/jayvee-language-server'; import { Logger } from '../logger'; +import { Workbook } from '../types'; import { FileSystem } from '../types/io-types/filesystem'; import { BinaryFile } from '../types/io-types/filesystem-node-file-binary'; import { TextFile } from '../types/io-types/filesystem-node-file-text'; @@ -134,6 +135,12 @@ export class DebugLogVisitor implements IoTypeVisitor { this.log('... (omitted in peek mode)'); } + visitWorkbook(workbook: Workbook): void { + this.log(`WorkSheets in WorkBook:`); + workbook + .getSheets() + .forEach((sheet) => console.log(`WorkSheet: ${sheet.getSheetName()}`)); + } private log(text: string): void { this.logger.logDebug(`[${this.logPrefix}] ${text}`); diff --git a/libs/execution/src/lib/types/io-types/index.ts b/libs/execution/src/lib/types/io-types/index.ts index fd270c9a1..c4d8d7deb 100644 --- a/libs/execution/src/lib/types/io-types/index.ts +++ b/libs/execution/src/lib/types/io-types/index.ts @@ -6,6 +6,7 @@ export * from './filesystem'; export * from './filesystem-inmemory'; export * from './io-type-implementation'; export * from './none'; +export * from './workbook'; export * from './sheet'; export * from './table'; export * from './filesystem-node-file-binary'; diff --git a/libs/execution/src/lib/types/io-types/io-type-implementation.ts b/libs/execution/src/lib/types/io-types/io-type-implementation.ts index 7f27edac4..e769f7ed2 100644 --- a/libs/execution/src/lib/types/io-types/io-type-implementation.ts +++ b/libs/execution/src/lib/types/io-types/io-type-implementation.ts @@ -10,6 +10,7 @@ import { type TextFile } from './filesystem-node-file-text'; import { type None } from './none'; import { type Sheet } from './sheet'; import { type Table } from './table'; +import { type Workbook } from './workbook'; export interface IOTypeImplementation { ioType: T; @@ -20,6 +21,7 @@ export interface IOTypeImplementation { export interface IoTypeVisitor { visitTable(table: Table): R; visitSheet(sheet: Sheet): R; + visitWorkbook(workbook: Workbook): R; visitNone(none: None): R; visitFileSystem(fileSystem: FileSystem): R; visitBinaryFile(binaryFile: BinaryFile): R; diff --git a/libs/execution/src/lib/types/io-types/sheet.ts b/libs/execution/src/lib/types/io-types/sheet.ts index 662709621..f294bbbc2 100644 --- a/libs/execution/src/lib/types/io-types/sheet.ts +++ b/libs/execution/src/lib/types/io-types/sheet.ts @@ -22,13 +22,17 @@ export class Sheet implements IOTypeImplementation { public readonly ioType = IOType.SHEET; private numberOfRows: number; private numberOfColumns: number; - constructor(private data: string[][]) { + constructor(private data: string[][], private sheetName?: string) { this.numberOfRows = data.length; this.numberOfColumns = data.reduce((prev, curr) => { return curr.length > prev ? curr.length : prev; }, 0); } + getSheetName(): string { + return this.sheetName ?? ''; + } + getData(): ReadonlyArray> { return this.data; } diff --git a/libs/execution/src/lib/types/io-types/workbook.ts b/libs/execution/src/lib/types/io-types/workbook.ts new file mode 100644 index 000000000..404567631 --- /dev/null +++ b/libs/execution/src/lib/types/io-types/workbook.ts @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { strict as assert } from 'assert'; + +import { IOType } from '@jvalue/jayvee-language-server'; + +import { IOTypeImplementation, IoTypeVisitor } from './io-type-implementation'; +import { Sheet } from './sheet'; + +export class Workbook implements IOTypeImplementation { + public readonly ioType = IOType.WORKBOOK; + private sheets: Sheet[]; + constructor() { + this.sheets = []; + } + + getSheets(): ReadonlyArray { + return this.sheets; + } + + getSheetByName(sheetName: string): Sheet { + const sheet = this.sheets.filter( + (sheet) => sheet.getSheetName() === sheetName, + )[0]; + assert(sheet instanceof Sheet); + return sheet; + } + + addSheet(sheet: Sheet) { + this.sheets.push(sheet); + } + + addNewSheet(data: string[][], sheetName?: string) { + const sheetNameOrDefault = sheetName ?? `Sheet${this.sheets.length + 1}`; + if ( + this.sheets.some((sheet) => sheet.getSheetName() === sheetNameOrDefault) + ) + return; + this.addSheet(new Sheet(data, sheetNameOrDefault)); + } + + acceptVisitor(visitor: IoTypeVisitor): R { + return visitor.visitWorkbook(this); + } +} diff --git a/libs/extensions/tabular/exec/src/extension.ts b/libs/extensions/tabular/exec/src/extension.ts index 680fb41ff..80746ca92 100644 --- a/libs/extensions/tabular/exec/src/extension.ts +++ b/libs/extensions/tabular/exec/src/extension.ts @@ -12,8 +12,10 @@ import { CellWriterExecutor } from './lib/cell-writer-executor'; import { ColumnDeleterExecutor } from './lib/column-deleter-executor'; import { CSVInterpreterExecutor } from './lib/csv-interpreter-executor'; import { RowDeleterExecutor } from './lib/row-deleter-executor'; +import { SheetPickerExecutor } from './lib/sheet-picker-executor'; import { TableInterpreterExecutor } from './lib/table-interpreter-executor'; import { TableTransformerExecutor } from './lib/table-transformer-executor'; +import { XLSXInterpreterExecutor } from './lib/xlsx-interpreter-executor'; export class TabularExecExtension implements JayveeExecExtension { getBlockExecutors(): BlockExecutorClass[] { @@ -25,6 +27,8 @@ export class TabularExecExtension implements JayveeExecExtension { TableInterpreterExecutor, CSVInterpreterExecutor, TableTransformerExecutor, + XLSXInterpreterExecutor, + SheetPickerExecutor, ]; } } diff --git a/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts new file mode 100644 index 000000000..f6a167ab2 --- /dev/null +++ b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import * as R from '@jvalue/jayvee-execution'; +import { + AbstractBlockExecutor, + BlockExecutorClass, + ExecutionContext, + Sheet, + Workbook, + implementsStatic, +} from '@jvalue/jayvee-execution'; +import { IOType, PrimitiveValuetypes } from '@jvalue/jayvee-language-server'; + +@implementsStatic() +export class SheetPickerExecutor extends AbstractBlockExecutor< + IOType.WORKBOOK, + IOType.SHEET +> { + public static readonly type = 'SheetPicker'; + + constructor() { + super(IOType.WORKBOOK, IOType.SHEET); + } + + // eslint-disable-next-line @typescript-eslint/require-await + async doExecute( + workbook: Workbook, + context: ExecutionContext, + ): Promise> { + const sheetName = context.getPropertyValue( + 'sheetName', + PrimitiveValuetypes.Text, + ); + const sheet = workbook.getSheetByName(sheetName); + return R.ok(sheet); + } +} diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts new file mode 100644 index 000000000..72186e150 --- /dev/null +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { strict as assert } from 'assert'; + +import * as R from '@jvalue/jayvee-execution'; +import { + AbstractBlockExecutor, + BinaryFile, + BlockExecutorClass, + ExecutionContext, + Workbook, + implementsStatic, +} from '@jvalue/jayvee-execution'; +import { IOType } from '@jvalue/jayvee-language-server'; +import * as xlsx from 'xlsx'; + +@implementsStatic() +export class XLSXInterpreterExecutor extends AbstractBlockExecutor< + IOType.FILE, + IOType.WORKBOOK +> { + public static readonly type = 'XLSXInterpreter'; + + constructor() { + super(IOType.FILE, IOType.WORKBOOK); + } + + async doExecute( + file: BinaryFile, + context: ExecutionContext, + ): Promise> { + context.logger.logDebug(`reading from xlsx file`); + const workBookFromFile = xlsx.read(file.content, { dense: true }); + const workbook = new Workbook(); + for (const workSheetName of workBookFromFile.SheetNames) { + const workSheet = workBookFromFile.Sheets[workSheetName]; + assert(workSheet !== undefined); + + const workSheetDataArray = Array.prototype.map.call< + xlsx.WorkSheet, + [ + callbackfn: ( + value: xlsx.CellObject[], + index: number, + array: xlsx.WorkSheet[], + ) => string[], + ], + string[][] + >(workSheet, (row: xlsx.CellObject[]): string[] => { + return row.map((cell: xlsx.CellObject) => { + return cell.v?.toString() ?? ''; + }); + }); + + workbook.addNewSheet(workSheetDataArray, workSheetName); + } + return Promise.resolve(R.ok(workbook)); + } +} diff --git a/libs/extensions/tabular/lang/src/extension.ts b/libs/extensions/tabular/lang/src/extension.ts index f2b9f1a1f..959be5362 100644 --- a/libs/extensions/tabular/lang/src/extension.ts +++ b/libs/extensions/tabular/lang/src/extension.ts @@ -13,8 +13,10 @@ import { CellWriterMetaInformation } from './lib/cell-writer-meta-inf'; import { ColumnDeleterMetaInformation } from './lib/column-deleter-meta-inf'; import { CSVInterpreterMetaInformation } from './lib/csv-interpreter-meta-inf'; import { RowDeleterMetaInformation } from './lib/row-deleter-meta-inf'; +import { SheetPickerMetaInformation } from './lib/sheet-picker-meta-inf'; import { TableInterpreterMetaInformation } from './lib/table-interpreter-meta-inf'; import { TableTransformerMetaInformation } from './lib/table-transformer-meta-inf'; +import { XLSXInterpreterMetaInformation } from './lib/xlsx-interpreter-meta-inf'; export class TabularLangExtension implements JayveeLangExtension { getBlockMetaInf(): Array> { @@ -26,6 +28,8 @@ export class TabularLangExtension implements JayveeLangExtension { TableInterpreterMetaInformation, CSVInterpreterMetaInformation, TableTransformerMetaInformation, + XLSXInterpreterMetaInformation, + SheetPickerMetaInformation, ]; } } diff --git a/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts new file mode 100644 index 000000000..518560040 --- /dev/null +++ b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { + BlockMetaInformation, + IOType, + PrimitiveValuetypes, +} from '@jvalue/jayvee-language-server'; + +export class SheetPickerMetaInformation extends BlockMetaInformation { + constructor() { + super( + // How the block type should be called: + 'SheetPicker', + // Property definitions: + { + sheetName: { + type: PrimitiveValuetypes.Text, + docs: { + description: 'The name of the sheet to select.', + }, + }, + }, + // Input type: + IOType.WORKBOOK, + + // Output type: + IOType.SHEET, + ); + + this.docs.description = + 'Selects one `Sheet` from a `Workbook` based on its `sheetName`. If no sheet matches the name, no output is created and the execution of the pipeline is aborted.'; + this.docs.examples = [ + { + code: `block AgencySheetPicker oftype SheetPicker { + sheetName: "AgencyNames"; +}`, + description: + 'Tries to pick the sheet `AgencyNames` from the provided `Workbook`. If `AgencyNames` exists it is passed on as `Sheet`, if it does not exist the execution of the pipeline is aborted.', + }, + ]; + } +} diff --git a/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts new file mode 100644 index 000000000..f3e2366e0 --- /dev/null +++ b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { BlockMetaInformation, IOType } from '@jvalue/jayvee-language-server'; + +export class XLSXInterpreterMetaInformation extends BlockMetaInformation { + constructor() { + super( + // How the block type should be called: + 'XLSXInterpreter', + // Property definitions: + {}, + // Input type: + IOType.FILE, + + // Output type: + IOType.WORKBOOK, + ); + + this.docs.description = + "Interprets an input file as a xlsx-file and outputs a `Workbook` containing `Sheet`'s."; + this.docs.examples = [ + { + code: blockExample, + description: + "Interprets an input file as a xlsx-file and outputs a `Workbook` containing `Sheet`'s.", + }, + ]; + } +} +const blockExample = `block AgencyXLSXInterpreter oftype XLSXInterpreter { + }`; diff --git a/libs/language-server/src/lib/ast/model-util.ts b/libs/language-server/src/lib/ast/model-util.ts index 9dc2a3467..ff748af05 100644 --- a/libs/language-server/src/lib/ast/model-util.ts +++ b/libs/language-server/src/lib/ast/model-util.ts @@ -145,6 +145,7 @@ export enum IOType { TEXT_FILE = 'TextFile', FILE_SYSTEM = 'FileSystem', SHEET = 'Sheet', + WORKBOOK = 'Workbook', TABLE = 'Table', } diff --git a/package-lock.json b/package-lock.json index e8b741364..9dff5b79e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,8 @@ "vscode-languageclient": "^8.0.2", "vscode-languageserver": "^8.0.2", "vscode-languageserver-protocol": "^3.17.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "xlsx": "^0.18.5" }, "devDependencies": { "@babel/preset-react": "^7.14.5", @@ -7134,6 +7135,14 @@ "node": ">= 10.0.0" } }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -8440,6 +8449,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8878,6 +8899,14 @@ "node": ">= 0.12.0" } }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -9286,6 +9315,17 @@ "node": ">=10" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -12744,6 +12784,14 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.13.1.tgz", "integrity": "sha512-0eu5ULPS2c/jsa1lGFneEFFEdTbembJv8e4QKXeVJ3lm/5hyve06dlKZrpxmMwJt6rYen7sxmHHK2CLaXvWuWQ==" }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -21830,6 +21878,17 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -24325,6 +24384,22 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -24395,6 +24470,26 @@ "node": ">=8" } }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/xml-js": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", @@ -29847,6 +29942,11 @@ "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" }, + "adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -30819,6 +30919,15 @@ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" }, + "cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "requires": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -31131,6 +31240,11 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, + "codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==" + }, "collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -31448,6 +31562,11 @@ "yaml": "^1.10.0" } }, + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -33907,6 +34026,11 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.13.1.tgz", "integrity": "sha512-0eu5ULPS2c/jsa1lGFneEFFEdTbembJv8e4QKXeVJ3lm/5hyve06dlKZrpxmMwJt6rYen7sxmHHK2CLaXvWuWQ==" }, + "frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" + }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -40651,6 +40775,14 @@ } } }, + "ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "requires": { + "frac": "~1.1.2" + } + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -42402,6 +42534,16 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, + "wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==" + }, + "word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -42442,6 +42584,20 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "requires": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + } + }, "xml-js": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", diff --git a/package.json b/package.json index 0f4dd71a9..7a325dca3 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "vscode-languageclient": "^8.0.2", "vscode-languageserver": "^8.0.2", "vscode-languageserver-protocol": "^3.17.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "xlsx": "^0.18.5" }, "devDependencies": { "@babel/preset-react": "^7.14.5",