dynamo-query-engine 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/utils/validation.js +46 -3
- package/tests/unit/validation.test.js +61 -0
package/package.json
CHANGED
package/src/utils/validation.js
CHANGED
|
@@ -83,22 +83,65 @@ export function validateExpandField(field, gridConfig) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* Validates pagination model
|
|
86
|
+
* Validates pagination model and ensures numeric types
|
|
87
87
|
* @param {PaginationModel} paginationModel - Pagination model to validate
|
|
88
88
|
* @throws {Error} If pagination model is invalid
|
|
89
|
+
* @returns {PaginationModel} Normalized pagination model with numeric values
|
|
89
90
|
*/
|
|
90
91
|
export function validatePaginationModel(paginationModel) {
|
|
91
92
|
if (!paginationModel) {
|
|
92
93
|
throw new Error("paginationModel is required");
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
// Check if pageSize exists first
|
|
97
|
+
if (!paginationModel.pageSize) {
|
|
96
98
|
throw new Error("paginationModel.pageSize must be a positive number");
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
// Convert pageSize to number if it's a string
|
|
102
|
+
let pageSize = paginationModel.pageSize;
|
|
103
|
+
if (typeof pageSize === "string") {
|
|
104
|
+
pageSize = Number(pageSize);
|
|
105
|
+
if (isNaN(pageSize)) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`paginationModel.pageSize must be a valid number, received '${paginationModel.pageSize}'`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
// Mutate the original object to ensure downstream code uses the number
|
|
111
|
+
paginationModel.pageSize = pageSize;
|
|
112
|
+
} else if (typeof pageSize !== "number") {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`paginationModel.pageSize must be a number, received ${typeof pageSize}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (pageSize < 1) {
|
|
119
|
+
throw new Error("paginationModel.pageSize must be a positive number");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (pageSize > 1000) {
|
|
100
123
|
throw new Error(
|
|
101
124
|
"paginationModel.pageSize cannot exceed 1000 (DynamoDB limit)"
|
|
102
125
|
);
|
|
103
126
|
}
|
|
127
|
+
|
|
128
|
+
// Convert page to number if it exists and is a string
|
|
129
|
+
if (paginationModel.page !== undefined) {
|
|
130
|
+
let page = paginationModel.page;
|
|
131
|
+
if (typeof page === "string") {
|
|
132
|
+
page = Number(page);
|
|
133
|
+
if (isNaN(page)) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`paginationModel.page must be a valid number, received '${paginationModel.page}'`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
paginationModel.page = page;
|
|
139
|
+
} else if (typeof page !== "number") {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`paginationModel.page must be a number, received ${typeof page}`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return paginationModel;
|
|
104
147
|
}
|
|
@@ -311,6 +311,67 @@ describe("Validation Utils", () => {
|
|
|
311
311
|
validatePaginationModel({ pageSize: 2000 });
|
|
312
312
|
}).toThrow(/DynamoDB limit/);
|
|
313
313
|
});
|
|
314
|
+
|
|
315
|
+
describe("String to Number Conversion", () => {
|
|
316
|
+
it("should convert pageSize string to number", () => {
|
|
317
|
+
const paginationModel = { pageSize: "25" };
|
|
318
|
+
validatePaginationModel(paginationModel);
|
|
319
|
+
expect(paginationModel.pageSize).toBe(25);
|
|
320
|
+
expect(typeof paginationModel.pageSize).toBe("number");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should convert page string to number", () => {
|
|
324
|
+
const paginationModel = { pageSize: 25, page: "1" };
|
|
325
|
+
validatePaginationModel(paginationModel);
|
|
326
|
+
expect(paginationModel.page).toBe(1);
|
|
327
|
+
expect(typeof paginationModel.page).toBe("number");
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("should convert both pageSize and page strings to numbers", () => {
|
|
331
|
+
const paginationModel = { pageSize: "50", page: "2" };
|
|
332
|
+
validatePaginationModel(paginationModel);
|
|
333
|
+
expect(paginationModel.pageSize).toBe(50);
|
|
334
|
+
expect(paginationModel.page).toBe(2);
|
|
335
|
+
expect(typeof paginationModel.pageSize).toBe("number");
|
|
336
|
+
expect(typeof paginationModel.page).toBe("number");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should throw error for invalid pageSize string", () => {
|
|
340
|
+
expect(() => {
|
|
341
|
+
validatePaginationModel({ pageSize: "abc" });
|
|
342
|
+
}).toThrow("must be a valid number");
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it("should throw error for invalid page string", () => {
|
|
346
|
+
expect(() => {
|
|
347
|
+
validatePaginationModel({ pageSize: 25, page: "invalid" });
|
|
348
|
+
}).toThrow("must be a valid number");
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it("should throw error for non-string, non-number pageSize", () => {
|
|
352
|
+
expect(() => {
|
|
353
|
+
validatePaginationModel({ pageSize: true });
|
|
354
|
+
}).toThrow("must be a number");
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it("should throw error for object pageSize", () => {
|
|
358
|
+
expect(() => {
|
|
359
|
+
validatePaginationModel({ pageSize: { value: 25 } });
|
|
360
|
+
}).toThrow("must be a number");
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("should validate converted string pageSize against limits", () => {
|
|
364
|
+
expect(() => {
|
|
365
|
+
validatePaginationModel({ pageSize: "1001" });
|
|
366
|
+
}).toThrow("cannot exceed 1000");
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it("should validate converted string pageSize is positive", () => {
|
|
370
|
+
expect(() => {
|
|
371
|
+
validatePaginationModel({ pageSize: "0" });
|
|
372
|
+
}).toThrow("must be a positive number");
|
|
373
|
+
});
|
|
374
|
+
});
|
|
314
375
|
});
|
|
315
376
|
|
|
316
377
|
describe("Edge Cases", () => {
|