Skip to content

Commit

Permalink
Using Proxy to prevent against modification the original view model.
Browse files Browse the repository at this point in the history
Fixes #137
Fixes #229
  • Loading branch information
Siemienik committed Nov 20, 2023
1 parent b3befc9 commit 65c4f95
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
14 changes: 4 additions & 10 deletions packages/xlsx-renderer/src/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {}
Expand All @@ -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);
Expand All @@ -23,20 +21,16 @@ export class Renderer {
}

public async renderFromFile(templatePath: string, viewModel: unknown): Promise<Workbook> {
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<Workbook> {
const result = await this.render(async () => {
return this.render(async () => {
const template = new Workbook();
return await template.xlsx.load(templateArrayBuffer);
}, viewModel);

return await result;
}
}
21 changes: 21 additions & 0 deletions packages/xlsx-renderer/src/ViewModel.ts
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
export type ViewModel = any;

export const createVmProxyHandler = ()=> {
const data: Record<string | number, unknown> = {};

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
},
}
}
25 changes: 25 additions & 0 deletions packages/xlsx-renderer/tests/spec/cell-value-type.test.ts
Original file line number Diff line number Diff line change
@@ -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<Workbook> =>{
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);
});
});

0 comments on commit 65c4f95

Please sign in to comment.