From 72705abaa311609d7f33ed422e7dcfa4c995568b Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Wed, 26 Feb 2025 15:00:54 -0500 Subject: [PATCH 1/9] Add options to transform column names, set the origin, omit column headers. --- plugins/export-workbook/src/index.ts | 3 +- plugins/export-workbook/src/options.ts | 50 +++++++++++++ plugins/export-workbook/src/plugin.ts | 89 ++++++++++------------- plugins/export-workbook/src/utils.spec.ts | 23 ++++++ plugins/export-workbook/src/utils.ts | 30 ++++++++ 5 files changed, 144 insertions(+), 51 deletions(-) create mode 100644 plugins/export-workbook/src/options.ts create mode 100644 plugins/export-workbook/src/utils.spec.ts diff --git a/plugins/export-workbook/src/index.ts b/plugins/export-workbook/src/index.ts index 143b6608b..c6dfcb97a 100644 --- a/plugins/export-workbook/src/index.ts +++ b/plugins/export-workbook/src/index.ts @@ -2,7 +2,8 @@ import type { FlatfileEvent } from '@flatfile/listener' import type { TickFunction } from '@flatfile/plugin-job-handler' import { jobHandler } from '@flatfile/plugin-job-handler' -import { PluginOptions, exportRecords } from './plugin' +import { exportRecords } from './plugin' +import { PluginOptions } from './options' /** * Export records plugin for Flatfile. diff --git a/plugins/export-workbook/src/options.ts b/plugins/export-workbook/src/options.ts new file mode 100644 index 000000000..325fb3d28 --- /dev/null +++ b/plugins/export-workbook/src/options.ts @@ -0,0 +1,50 @@ +import type { Flatfile } from '@flatfile/api' + +/** + * A sheet address. + * + * @property {number} column - The column component + * @property {number} row - The row component + */ +export interface SheetAddress { + column: number; + row: number; +} + +/** + * Sheet specific options. + * + * @property {number | SheetAddress} origin - The sheet origin + * @property {boolean} skipColumnHeaders - If true, do not include column row in output + */ +export interface ExportSheetOptions { + origin?: number | SheetAddress; + skipColumnHeaders?: boolean; +} + +export type ColumnNameTransformerCallback = (columnName: string, sheetSlug: string) => string; + +/** + * Plugin config options. + * + * @property {string} jobName - name of the job + * @property {string[]} excludedSheets - list of sheet names to exclude from the exported data. + * @property {string[]} excludeFields - list of field names to exclude from the exported data. This applies to all sheets. + * @property {Flatfile.Filter} recordFilter - filter to apply to the records before exporting. + * @property {boolean} includeRecordIds - include record ids in the exported data. + * @property {boolean} autoDownload - auto download the file after exporting + * @property {boolean} debug - show helpful messages useful for debugging (use intended for development). + * @property {Record} sheetOptions - map of sheet slug to ExportSheetOptions. + * @property {ColumnNameTransformerCallback} columnNameTransformer - callback to transform column names. + */ +export interface PluginOptions { + readonly jobName?: string + readonly excludedSheets?: string[] + readonly excludeFields?: string[] + readonly recordFilter?: Flatfile.Filter + readonly includeRecordIds?: boolean + readonly autoDownload?: boolean + readonly debug?: boolean + readonly sheetOptions?: Record; + readonly columnNameTransformer?: ColumnNameTransformerCallback; +} diff --git a/plugins/export-workbook/src/plugin.ts b/plugins/export-workbook/src/plugin.ts index 81966178e..90a7a9a90 100644 --- a/plugins/export-workbook/src/plugin.ts +++ b/plugins/export-workbook/src/plugin.ts @@ -8,36 +8,24 @@ import * as fs from 'fs' import path from 'path' import * as R from 'remeda' import * as XLSX from 'xlsx' -import { sanitize, sanitizeExcelSheetName } from './utils' +import { + createXLSXSheetOptions, + sanitize, + sanitizeExcelSheetName, +} from './utils' +import { Comments } from 'xlsx' +import { PluginOptions } from './options' const api = new FlatfileClient() -/** - * Plugin config options. - * - * @property {string} jobName - name of the job - * @property {string[]} excludedSheets - list of sheet names to exclude from the exported data. - * @property {string[]} excludeFields - list of field names to exclude from the exported data. This applies to all sheets. - * @property {Flatfile.Filter} recordFilter - filter to apply to the records before exporting. - * @property {boolean} includeRecordIds - include record ids in the exported data. - * @property {boolean} autoDownload - auto download the file after exporting - * @property {boolean} debug - show helpul messages useful for debugging (use intended for development). - */ -export interface PluginOptions { - readonly jobName?: string - readonly excludedSheets?: string[] - readonly excludeFields?: string[] - readonly recordFilter?: Flatfile.Filter - readonly includeRecordIds?: boolean - readonly autoDownload?: boolean - readonly debug?: boolean -} +const LOG_NAME = '@flatfile/plugin-export-workbook' /** * Runs extractor and creates an `.xlsx` file with all Flatfile Workbook data. * * @param event - Flatfile event * @param options - plugin config options + * @param tick */ export const exportRecords = async ( event: FlatfileEvent, @@ -61,10 +49,7 @@ export const exportRecords = async ( }, '') ) - logInfo( - '@flatfile/plugin-export-workbook', - `Sheets found in Flatfile workbook: ${meta}` - ) + logInfo(LOG_NAME, `Sheets found in Flatfile workbook: ${meta}`) } const xlsxWorkbook = XLSX.utils.book_new() @@ -72,13 +57,16 @@ export const exportRecords = async ( for (const [sheetIndex, sheet] of sheets.entries()) { if (options.excludedSheets?.includes(sheet.config.slug)) { if (options.debug) { - logInfo( - '@flatfile/plugin-export-workbook', - `Skipping sheet: ${sheet.name}` - ) + logInfo(LOG_NAME, `Skipping sheet: ${sheet.name}`) } continue } + + const columnNameTransformer = options.columnNameTransformer + ? (name: string) => + options.columnNameTransformer(name, sheet.config.slug) + : (name: string) => name + try { let results = await processRecords[]>( sheet.id, @@ -95,7 +83,7 @@ export const exportRecords = async ( }) => { const rowValue = R.pipe( Object.keys(row), - R.reduce((acc, colName) => { + R.reduce((acc, colName: string) => { if (options.excludeFields?.includes(colName)) { return acc } @@ -104,14 +92,14 @@ export const exportRecords = async ( const cell: XLSX.CellObject = { t: 's', v: Array.isArray(value) ? value.join(', ') : value, - c: [], + c: [] as Comments, } if (R.length(messages) > 0) { cell.c = messages.map((m) => ({ a: 'Flatfile', t: `[${m.type.toUpperCase()}]: ${m.message}`, T: true, - })) + })) as Comments cell.c.hidden = true } @@ -120,7 +108,9 @@ export const exportRecords = async ( return { ...acc, - [colName]: formatCell(row[colName]), + [columnNameTransformer(colName)]: formatCell( + row[colName] + ), } }, {}) ) @@ -142,15 +132,20 @@ export const exportRecords = async ( const emptyCell: XLSX.CellObject = { t: 's', v: '', - c: [], + c: [] as Comments, } results = [ - sheet.config.fields.map((field) => ({ [field.key]: emptyCell })), + sheet.config.fields.map((field) => ({ + [columnNameTransformer(field.key)]: emptyCell, + })), ] } const rows = results.flat() - const worksheet = XLSX.utils.json_to_sheet(rows) + const worksheet = XLSX.utils.json_to_sheet( + rows, + createXLSXSheetOptions(options.sheetOptions?.[sheet.config.slug]) + ) XLSX.utils.book_append_sheet( xlsxWorkbook, @@ -163,7 +158,7 @@ export const exportRecords = async ( ) } catch (_) { logError( - '@flatfile/plugin-export-workbook', + LOG_NAME, `Failed to fetch records for sheet with id: ${sheet.id}` ) @@ -180,10 +175,7 @@ export const exportRecords = async ( if (xlsxWorkbook.SheetNames.length === 0) { if (options.debug) { - logError( - '@flatfile/plugin-export-workbook', - 'No data to write to Excel file' - ) + logError(LOG_NAME, 'No data to write to Excel file') } throw new Error('No data to write to Excel file.') @@ -196,13 +188,10 @@ export const exportRecords = async ( await tick(80, 'Excel file written to disk') if (options.debug) { - logInfo('@flatfile/plugin-export-workbook', 'File written to disk') + logInfo(LOG_NAME, 'File written to disk') } } catch (_) { - logError( - '@flatfile/plugin-export-workbook', - 'Failed to write file to disk' - ) + logError(LOG_NAME, 'Failed to write file to disk') throw new Error('Failed writing the Excel file to disk.') } @@ -226,18 +215,18 @@ export const exportRecords = async ( if (options.debug) { logInfo( - '@flatfile/plugin-export-workbook', + LOG_NAME, `Excel document uploaded. View file at https://spaces.flatfile.com/space/${spaceId}/files?mode=export` ) } } catch (_) { - logError('@flatfile/plugin-export-workbook', 'Failed to upload file') + logError(LOG_NAME, 'Failed to upload file') throw new Error('Failed uploading Excel file to Flatfile.') } if (options.debug) { - logInfo('@flatfile/plugin-export-workbook', 'Done') + logInfo(LOG_NAME, 'Done') } return options.autoDownload @@ -267,7 +256,7 @@ export const exportRecords = async ( }, } } catch (error) { - logError('@flatfile/plugin-export-workbook', error) + logError(LOG_NAME, error) throw new Error((error as Error).message) } diff --git a/plugins/export-workbook/src/utils.spec.ts b/plugins/export-workbook/src/utils.spec.ts new file mode 100644 index 000000000..491b8b34d --- /dev/null +++ b/plugins/export-workbook/src/utils.spec.ts @@ -0,0 +1,23 @@ +import { createXLSXSheetOptions } from './utils' +import { ExportSheetOptions } from './options' +import { JSON2SheetOpts } from 'xlsx' + +describe('createXLSXSheetOptions', () => { + it.each([ + [null, {}], + [undefined, {}], + [{}, {}], + [{ skipColumnHeaders: true }, { skipHeader: true }], + [{ skipColumnHeaders: false }, {}], + [ + { origin: 123, skipColumnHeaders: true }, + { origin: 123, skipHeader: true }, + ], + [{ origin: { row: 1, column: 2 } }, { origin: { r: 1, c: 2 } }], + ])( + 'createXLSXSheetOptions %o', + (options: ExportSheetOptions, expected: JSON2SheetOpts) => { + expect(createXLSXSheetOptions(options)).toEqual(expected) + } + ) +}) diff --git a/plugins/export-workbook/src/utils.ts b/plugins/export-workbook/src/utils.ts index f6833cb44..d1ba9992c 100644 --- a/plugins/export-workbook/src/utils.ts +++ b/plugins/export-workbook/src/utils.ts @@ -1,3 +1,6 @@ +import { ExportSheetOptions, SheetAddress } from './options' +import { JSON2SheetOpts, OriginOption } from 'xlsx' + export function sanitize(fileName: string): string { // List of invalid characters that are commonly not allowed in file names const invalidChars = /[\/\?%\*:|"<>]/g @@ -55,3 +58,30 @@ export const genCyclicPattern = (length: number = 104): Array => { return alphaPattern } + +/** + * Convert sheetOptions to JSON2SheetOpts. + * + * @param sheetOptions Sheet options + */ +export function createXLSXSheetOptions( + sheetOptions?: ExportSheetOptions +): JSON2SheetOpts { + const options: JSON2SheetOpts = {} + + if (sheetOptions?.origin) { + if (typeof sheetOptions.origin === 'number') { + options.origin = sheetOptions.origin + } else { + options.origin = { + c: sheetOptions.origin.column, + r: sheetOptions.origin.row, + } + } + } + + if (sheetOptions?.skipColumnHeaders) { + options.skipHeader = true + } + return options +} From 8957fe55501e4ef87c002292d01a4faa0a9a7189 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Wed, 26 Feb 2025 16:52:46 -0500 Subject: [PATCH 2/9] fix empty sheet bug --- plugins/export-workbook/src/plugin.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/export-workbook/src/plugin.ts b/plugins/export-workbook/src/plugin.ts index 90a7a9a90..14fc1aab4 100644 --- a/plugins/export-workbook/src/plugin.ts +++ b/plugins/export-workbook/src/plugin.ts @@ -134,10 +134,16 @@ export const exportRecords = async ( v: '', c: [] as Comments, } + results = [ - sheet.config.fields.map((field) => ({ - [columnNameTransformer(field.key)]: emptyCell, - })), + [ + Object.fromEntries( + sheet.config.fields.map((field) => [ + columnNameTransformer(field.key), + emptyCell, + ]) + ), + ], ] } const rows = results.flat() From ac432d0838e4142eed356679d0a5549a94f630e3 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Thu, 27 Feb 2025 08:39:31 -0500 Subject: [PATCH 3/9] changeset --- .changeset/fluffy-pillows-call.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fluffy-pillows-call.md diff --git a/.changeset/fluffy-pillows-call.md b/.changeset/fluffy-pillows-call.md new file mode 100644 index 000000000..66b4c3cb8 --- /dev/null +++ b/.changeset/fluffy-pillows-call.md @@ -0,0 +1,5 @@ +--- +'@flatfile/plugin-export-workbook': minor +--- + +Added options to adjust the origin and column headers From 2813247be853c8ece5dd7b1e9249e5c78933b4b8 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Thu, 27 Feb 2025 08:47:40 -0500 Subject: [PATCH 4/9] pr feedback --- plugins/export-workbook/src/plugin.ts | 7 +++---- plugins/export-workbook/src/utils.ts | 5 ++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/export-workbook/src/plugin.ts b/plugins/export-workbook/src/plugin.ts index 14fc1aab4..864896475 100644 --- a/plugins/export-workbook/src/plugin.ts +++ b/plugins/export-workbook/src/plugin.ts @@ -13,7 +13,6 @@ import { sanitize, sanitizeExcelSheetName, } from './utils' -import { Comments } from 'xlsx' import { PluginOptions } from './options' const api = new FlatfileClient() @@ -92,14 +91,14 @@ export const exportRecords = async ( const cell: XLSX.CellObject = { t: 's', v: Array.isArray(value) ? value.join(', ') : value, - c: [] as Comments, + c: [], } if (R.length(messages) > 0) { cell.c = messages.map((m) => ({ a: 'Flatfile', t: `[${m.type.toUpperCase()}]: ${m.message}`, T: true, - })) as Comments + })) cell.c.hidden = true } @@ -132,7 +131,7 @@ export const exportRecords = async ( const emptyCell: XLSX.CellObject = { t: 's', v: '', - c: [] as Comments, + c: [], } results = [ diff --git a/plugins/export-workbook/src/utils.ts b/plugins/export-workbook/src/utils.ts index d1ba9992c..b49cb4b61 100644 --- a/plugins/export-workbook/src/utils.ts +++ b/plugins/export-workbook/src/utils.ts @@ -72,7 +72,10 @@ export function createXLSXSheetOptions( if (sheetOptions?.origin) { if (typeof sheetOptions.origin === 'number') { options.origin = sheetOptions.origin - } else { + } else if ( + 'column' in sheetOptions.origin && + 'row' in sheetOptions.origin + ) { options.origin = { c: sheetOptions.origin.column, r: sheetOptions.origin.row, From c95c0a5fd87114911a28f8f0431b81a8ea6a3da9 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Tue, 11 Mar 2025 10:54:32 -0400 Subject: [PATCH 5/9] lint --- plugins/export-workbook/src/options.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/export-workbook/src/options.ts b/plugins/export-workbook/src/options.ts index 325fb3d28..dea72fbca 100644 --- a/plugins/export-workbook/src/options.ts +++ b/plugins/export-workbook/src/options.ts @@ -7,8 +7,8 @@ import type { Flatfile } from '@flatfile/api' * @property {number} row - The row component */ export interface SheetAddress { - column: number; - row: number; + column: number + row: number } /** @@ -18,11 +18,14 @@ export interface SheetAddress { * @property {boolean} skipColumnHeaders - If true, do not include column row in output */ export interface ExportSheetOptions { - origin?: number | SheetAddress; - skipColumnHeaders?: boolean; + origin?: number | SheetAddress + skipColumnHeaders?: boolean } -export type ColumnNameTransformerCallback = (columnName: string, sheetSlug: string) => string; +export type ColumnNameTransformerCallback = ( + columnName: string, + sheetSlug: string +) => string /** * Plugin config options. @@ -45,6 +48,6 @@ export interface PluginOptions { readonly includeRecordIds?: boolean readonly autoDownload?: boolean readonly debug?: boolean - readonly sheetOptions?: Record; - readonly columnNameTransformer?: ColumnNameTransformerCallback; + readonly sheetOptions?: Record + readonly columnNameTransformer?: ColumnNameTransformerCallback } From 0a1bffc3403ddabb3a69b867aca123f0e5aedbd6 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Thu, 13 Mar 2025 08:19:18 -0400 Subject: [PATCH 6/9] pr nits --- .changeset/fluffy-pillows-call.md | 2 +- plugins/export-workbook/src/index.ts | 2 +- plugins/export-workbook/src/plugin.ts | 26 +++++++++++++------------- plugins/export-workbook/src/utils.ts | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.changeset/fluffy-pillows-call.md b/.changeset/fluffy-pillows-call.md index 66b4c3cb8..ff928f3fa 100644 --- a/.changeset/fluffy-pillows-call.md +++ b/.changeset/fluffy-pillows-call.md @@ -1,5 +1,5 @@ --- -'@flatfile/plugin-export-workbook': minor +'@flatfile/plugin-export-workbook': major --- Added options to adjust the origin and column headers diff --git a/plugins/export-workbook/src/index.ts b/plugins/export-workbook/src/index.ts index c6dfcb97a..185156299 100644 --- a/plugins/export-workbook/src/index.ts +++ b/plugins/export-workbook/src/index.ts @@ -3,7 +3,7 @@ import type { TickFunction } from '@flatfile/plugin-job-handler' import { jobHandler } from '@flatfile/plugin-job-handler' import { exportRecords } from './plugin' -import { PluginOptions } from './options' +import type { PluginOptions } from './options' /** * Export records plugin for Flatfile. diff --git a/plugins/export-workbook/src/plugin.ts b/plugins/export-workbook/src/plugin.ts index 864896475..f8563e6b1 100644 --- a/plugins/export-workbook/src/plugin.ts +++ b/plugins/export-workbook/src/plugin.ts @@ -13,18 +13,18 @@ import { sanitize, sanitizeExcelSheetName, } from './utils' -import { PluginOptions } from './options' +import type { PluginOptions } from './options' const api = new FlatfileClient() -const LOG_NAME = '@flatfile/plugin-export-workbook' +import { name as PACKAGE_NAME } from '../package.json' /** * Runs extractor and creates an `.xlsx` file with all Flatfile Workbook data. * * @param event - Flatfile event * @param options - plugin config options - * @param tick + * @param tick - a function to update job progress */ export const exportRecords = async ( event: FlatfileEvent, @@ -48,7 +48,7 @@ export const exportRecords = async ( }, '') ) - logInfo(LOG_NAME, `Sheets found in Flatfile workbook: ${meta}`) + logInfo(PACKAGE_NAME, `Sheets found in Flatfile workbook: ${meta}`) } const xlsxWorkbook = XLSX.utils.book_new() @@ -56,7 +56,7 @@ export const exportRecords = async ( for (const [sheetIndex, sheet] of sheets.entries()) { if (options.excludedSheets?.includes(sheet.config.slug)) { if (options.debug) { - logInfo(LOG_NAME, `Skipping sheet: ${sheet.name}`) + logInfo(PACKAGE_NAME, `Skipping sheet: ${sheet.name}`) } continue } @@ -163,7 +163,7 @@ export const exportRecords = async ( ) } catch (_) { logError( - LOG_NAME, + PACKAGE_NAME, `Failed to fetch records for sheet with id: ${sheet.id}` ) @@ -180,7 +180,7 @@ export const exportRecords = async ( if (xlsxWorkbook.SheetNames.length === 0) { if (options.debug) { - logError(LOG_NAME, 'No data to write to Excel file') + logError(PACKAGE_NAME, 'No data to write to Excel file') } throw new Error('No data to write to Excel file.') @@ -193,10 +193,10 @@ export const exportRecords = async ( await tick(80, 'Excel file written to disk') if (options.debug) { - logInfo(LOG_NAME, 'File written to disk') + logInfo(PACKAGE_NAME, 'File written to disk') } } catch (_) { - logError(LOG_NAME, 'Failed to write file to disk') + logError(PACKAGE_NAME, 'Failed to write file to disk') throw new Error('Failed writing the Excel file to disk.') } @@ -220,18 +220,18 @@ export const exportRecords = async ( if (options.debug) { logInfo( - LOG_NAME, + PACKAGE_NAME, `Excel document uploaded. View file at https://spaces.flatfile.com/space/${spaceId}/files?mode=export` ) } } catch (_) { - logError(LOG_NAME, 'Failed to upload file') + logError(PACKAGE_NAME, 'Failed to upload file') throw new Error('Failed uploading Excel file to Flatfile.') } if (options.debug) { - logInfo(LOG_NAME, 'Done') + logInfo(PACKAGE_NAME, 'Done') } return options.autoDownload @@ -261,7 +261,7 @@ export const exportRecords = async ( }, } } catch (error) { - logError(LOG_NAME, error) + logError(PACKAGE_NAME, error) throw new Error((error as Error).message) } diff --git a/plugins/export-workbook/src/utils.ts b/plugins/export-workbook/src/utils.ts index b49cb4b61..96a61f134 100644 --- a/plugins/export-workbook/src/utils.ts +++ b/plugins/export-workbook/src/utils.ts @@ -1,5 +1,5 @@ -import { ExportSheetOptions, SheetAddress } from './options' -import { JSON2SheetOpts, OriginOption } from 'xlsx' +import { ExportSheetOptions } from './options' +import { JSON2SheetOpts } from 'xlsx' export function sanitize(fileName: string): string { // List of invalid characters that are commonly not allowed in file names From f5d3b7cdd7b93f84a814497db3a35557a6247e50 Mon Sep 17 00:00:00 2001 From: Amit Lissack Date: Thu, 13 Mar 2025 09:09:33 -0400 Subject: [PATCH 7/9] README --- plugins/export-workbook/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/plugins/export-workbook/README.md b/plugins/export-workbook/README.md index 455fe3c7c..9d199c125 100644 --- a/plugins/export-workbook/README.md +++ b/plugins/export-workbook/README.md @@ -44,7 +44,36 @@ Automatically download the file after exporting The `debug` parameter lets you toggle on/off helpful debugging messages for development purposes. +#### `sheetOptions` - `Record` - (optional) + +A map of sheet slug to `ExportSheetOptions` instance providing sheet specific export options: + +- `skipColumnHeaders` - `boolean` - (optional) - allows omitting column headers +- `origin` - `number` | `SheetAddress` - (optional) - allows offsetting the start of a sheet. The parameter is either a row number or an object with `column` and `row`. + +Usage: + +```typescript +listener.use( + exportWorkbookPlugin({ + sheetOptions: { + SomeSheetSlug: { + // Start the sheet at 5 + origin: 5, + // Omit column headers + skipColumnHeaders: true, + }, + SomeOtherSheetSlug: { + // Start the sheet at row 10 column 2 + origin: {row: 10, column: 2}, + }, + }, + }) +``` + +#### `columnNameTransformer` - `ColumnNameTransformerCallback` - (optional) +A callback function allowing changing how column names appear in the workbook. The function accepts two arguments: `columnName` and `sheetSlug` and returns a new column name. ## Usage From ba2d2c394921879543e67bfd57151c3d6a0ed866 Mon Sep 17 00:00:00 2001 From: amit lissack Date: Thu, 13 Mar 2025 09:16:35 -0400 Subject: [PATCH 8/9] Update plugins/export-workbook/src/utils.ts Co-authored-by: Carl Brugger --- plugins/export-workbook/src/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/export-workbook/src/utils.ts b/plugins/export-workbook/src/utils.ts index 96a61f134..4f8970284 100644 --- a/plugins/export-workbook/src/utils.ts +++ b/plugins/export-workbook/src/utils.ts @@ -1,5 +1,5 @@ -import { ExportSheetOptions } from './options' -import { JSON2SheetOpts } from 'xlsx' +import type { ExportSheetOptions } from './options' +import type { JSON2SheetOpts } from 'xlsx' export function sanitize(fileName: string): string { // List of invalid characters that are commonly not allowed in file names From 09d27f995ba6f16270d42c13ece2287eaa1b23d4 Mon Sep 17 00:00:00 2001 From: amit lissack Date: Thu, 13 Mar 2025 13:06:36 -0400 Subject: [PATCH 9/9] Update plugins/export-workbook/src/utils.spec.ts Co-authored-by: Carl Brugger --- plugins/export-workbook/src/utils.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/export-workbook/src/utils.spec.ts b/plugins/export-workbook/src/utils.spec.ts index 491b8b34d..62fa41af1 100644 --- a/plugins/export-workbook/src/utils.spec.ts +++ b/plugins/export-workbook/src/utils.spec.ts @@ -1,6 +1,6 @@ import { createXLSXSheetOptions } from './utils' -import { ExportSheetOptions } from './options' -import { JSON2SheetOpts } from 'xlsx' +import type { ExportSheetOptions } from './options' +import type { JSON2SheetOpts } from 'xlsx' describe('createXLSXSheetOptions', () => { it.each([