diff --git a/packages/xlsx-renderer/src/Renderer.ts b/packages/xlsx-renderer/src/Renderer.ts index 5fb357c..b4c5a0a 100644 --- a/packages/xlsx-renderer/src/Renderer.ts +++ b/packages/xlsx-renderer/src/Renderer.ts @@ -2,6 +2,7 @@ import { Workbook } from 'exceljs'; import { Scope } from './Scope'; import { CellTemplatePool } from './CellTemplatePool'; +import { createVmProxyHandler } from './ViewModel'; export class Renderer { constructor(private cellTemplatePool: CellTemplatePool = new CellTemplatePool()) {} @@ -10,10 +11,7 @@ export class Renderer { const template = await templateFactory(); const output = await templateFactory(); - // todo Temporary fixation for VM mutating problem, @see https://github.com/Siemienik/XToolset/issues/137 - const vmCopy = JSON.parse(JSON.stringify(vm)); - - const scope = new Scope(template, output, vmCopy); + const scope = new Scope(template, output, new Proxy(vm, createVmProxyHandler())); while (!scope.isFinished()) { this.cellTemplatePool.match(scope.getCurrentTemplateCell()).apply(scope); @@ -23,20 +21,16 @@ export class Renderer { } public async renderFromFile(templatePath: string, viewModel: unknown): Promise { - const result = await this.render(async () => { + return this.render(async () => { const template = new Workbook(); return await template.xlsx.readFile(templatePath); }, viewModel); - - return await result; } public async renderFromArrayBuffer(templateArrayBuffer: ArrayBuffer, viewModel: unknown): Promise { - const result = await this.render(async () => { + return this.render(async () => { const template = new Workbook(); return await template.xlsx.load(templateArrayBuffer); }, viewModel); - - return await result; } } diff --git a/packages/xlsx-renderer/src/ViewModel.ts b/packages/xlsx-renderer/src/ViewModel.ts index e5671f0..09481fd 100644 --- a/packages/xlsx-renderer/src/ViewModel.ts +++ b/packages/xlsx-renderer/src/ViewModel.ts @@ -1 +1,22 @@ export type ViewModel = any; + +export const createVmProxyHandler = ()=> { + const data: Record = {}; + + return { + get(target: any, p: PropertyKey): any { + if (typeof p !== 'string' && typeof p !== 'number') { + return; + } + return p in data ? data[p] : target[p] + }, + set(target: unknown, p: PropertyKey, value: unknown): boolean { + if (typeof p !== 'string' && typeof p !== 'number') { + return false; + } + data[p] = value + + return true + }, + } +} diff --git a/packages/xlsx-renderer/tests/spec/cell-value-type.test.ts b/packages/xlsx-renderer/tests/spec/cell-value-type.test.ts new file mode 100644 index 0000000..e8a956d --- /dev/null +++ b/packages/xlsx-renderer/tests/spec/cell-value-type.test.ts @@ -0,0 +1,25 @@ +import * as chai from 'chai'; +import { CellValue, Workbook } from 'exceljs'; +import { ValueType } from 'exceljs'; +import { Renderer } from '../../src/Renderer'; + +const WS_NAME = 'test ws'; + +describe('BaseCell unit tests', () => { + const factory = async ():Promise =>{ + const template = new Workbook(); + template.addWorksheet(WS_NAME).addRow(['## testVar', "#! FINISH"]); + + return template; + } + + it('DateTime', async () => { + const viewModel = { + testVar: new Date(2023, 11, 17, 21, 37) + } + const renderer = new Renderer(); + const output = await renderer.render(factory, viewModel) + + chai.expect(output.getWorksheet(WS_NAME)?.getCell('A1').type).equals(ValueType.Date); + }); +});