Skip to content

Commit ec8a44d

Browse files
committed
zod type validation
1 parent 3688014 commit ec8a44d

File tree

3 files changed

+51
-34
lines changed

3 files changed

+51
-34
lines changed

package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@univerjs/sheets": "^0.2.15",
3232
"@univerjs/sheets-formula": "^0.2.15",
3333
"@univerjs/sheets-ui": "^0.2.15",
34-
"@univerjs/ui": "^0.2.15"
34+
"@univerjs/ui": "^0.2.15",
35+
"zod": "^3.23.8"
3536
}
3637
}

spreadsheet.ts

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ import { UniverSheetsFormulaPlugin } from "@univerjs/sheets-formula";
3737
import { UniverSheetsNumfmtPlugin } from "@univerjs/sheets-numfmt";
3838
import { UniverSheetsUIPlugin } from "@univerjs/sheets-ui";
3939

40+
import { z } from "zod";
41+
42+
const PropsSchema = z.object({
43+
update_link: z.string().url(),
44+
freeze_x: z.number().int().nonnegative(),
45+
freeze_y: z.number().int().nonnegative(),
46+
component_index: z.number().int().nonnegative(),
47+
});
48+
49+
type Props = z.infer<typeof PropsSchema>;
50+
4051
function setupUniver(component_index: number) {
4152
const univer = new Univer({
4253
theme: defaultTheme,
@@ -99,9 +110,17 @@ async function handleUpdate(
99110
}
100111
}
101112

102-
function cellFromProps(
103-
props: (string | number)[],
104-
): Partial<IStyleData & { id: string }> {
113+
const CellPropsSchema = z.union([z.string(), z.number()]);
114+
115+
const DataArraySchema = z.tuple([
116+
z.number().int().nonnegative(), // colIdx
117+
z.number().int().nonnegative(), // rowIdx
118+
z.union([z.string(), z.number(), z.null()]), // value
119+
]).rest(CellPropsSchema); // props
120+
121+
type CellProps = z.infer<typeof CellPropsSchema>;
122+
123+
function cellFromProps(props: CellProps[]) {
105124
const s: Partial<IStyleData & { id: string }> = {};
106125
for (let i = 0; i < props.length; i++) {
107126
const n = props[i];
@@ -124,22 +143,13 @@ function cellFromProps(
124143
return s;
125144
}
126145

127-
/**
128-
* [colIdx, rowIdx, value, ...props]
129-
*/
130-
type DataArray = [
131-
number,
132-
number,
133-
string | number | null,
134-
...(string | number)[],
135-
];
136-
137-
function generateWorkSheet(dataArray: DataArray[]): Partial<IWorksheetData> {
146+
function generateWorkSheet(dataArray: any[]): Partial<IWorksheetData> {
138147
const cellData: IObjectMatrixPrimitiveType<ICellData> = {};
139148
let rowCount = 1000;
140149
let columnCount = 26;
141150

142-
for (const [colIdx, rowIdx, value, ...props] of dataArray) {
151+
for (const elem of dataArray) {
152+
const [colIdx, rowIdx, value, ...props] = DataArraySchema.parse(elem);
143153
const cell: Partial<ICellData> = { v: value };
144154
const style = props.length ? cellFromProps(props) : null;
145155
cell.s = style;
@@ -161,7 +171,7 @@ function generateWorkSheet(dataArray: DataArray[]): Partial<IWorksheetData> {
161171
};
162172
}
163173

164-
function createWorkbook(univer: Univer, data: DataArray[]): Workbook {
174+
function createWorkbook(univer: Univer, data: any[]): Workbook {
165175
return univer.createUnit<IWorkbookData, Workbook>(
166176
UniverInstanceType.UNIVER_SHEET,
167177
{
@@ -194,19 +204,8 @@ function setFrozenCells(
194204
}
195205
}
196206

197-
async function renderSpreadsheet({
198-
update_link,
199-
freeze_x,
200-
freeze_y,
201-
component_index,
202-
data,
203-
}: {
204-
update_link: string;
205-
freeze_x: number;
206-
freeze_y: number;
207-
component_index: number;
208-
data: DataArray[];
209-
}) {
207+
async function renderSpreadsheet(props: Props, data: any[]) {
208+
const { update_link, freeze_x, freeze_y, component_index } = props;
210209
const errorModal = setupErrorModal(component_index);
211210
const univer = setupUniver(component_index);
212211
const univerAPI = FUniver.newAPI(univer);
@@ -240,7 +239,14 @@ async function renderSpreadsheet({
240239
});
241240
}
242241

243-
const props = JSON.parse(
244-
document?.currentScript?.dataset?.template_props || "{}",
242+
const rawProps = JSON.parse(
243+
document?.currentScript?.dataset?.template_props || "{}"
245244
);
246-
renderSpreadsheet(props);
245+
246+
try {
247+
const validatedProps = PropsSchema.parse(rawProps.props);
248+
const data = z.any().array().parse(rawProps.data); // will be fully validated later
249+
renderSpreadsheet(validatedProps, data);
250+
} catch (error) {
251+
alert(`Invalid properties passed to the spreadsheet component: ${error}`);
252+
}

0 commit comments

Comments
 (0)