|
6 | 6 | import type { IFolder, INode } from '../node/index.ts' |
7 | 7 |
|
8 | 8 | import isSvg from 'is-svg' |
9 | | -import { Column } from './column.ts' |
| 9 | +import { Column, validateColumn } from './column.ts' |
| 10 | +import { checkOptionalProperty } from '../utils/objectValidation.ts' |
10 | 11 |
|
11 | 12 | export type ContentsWithRoot = { |
12 | 13 | folder: IFolder, |
@@ -241,37 +242,13 @@ export function validateView(view: IView) { |
241 | 242 | checkOptionalProperty(view, 'sticky', 'boolean') |
242 | 243 |
|
243 | 244 | if (view.columns) { |
244 | | - view.columns.forEach((column) => { |
245 | | - if (!(column instanceof Column)) { |
246 | | - throw new Error('View columns must be an array of Column. Invalid column found') |
247 | | - } |
248 | | - }) |
249 | | - } |
250 | | -} |
251 | | - |
252 | | -/** |
253 | | - * Check an optional property type |
254 | | - * |
255 | | - * @param obj - the object to check |
256 | | - * @param property - the property name |
257 | | - * @param type - the expected type |
258 | | - * @throws {Error} if the property is defined and not of the expected type |
259 | | - */ |
260 | | -function checkOptionalProperty( |
261 | | - obj: Partial<IView>, |
262 | | - property: keyof IView, |
263 | | - type: 'array' | 'function' | 'string' | 'boolean' | 'number' | 'object', |
264 | | -): void { |
265 | | - if (typeof obj[property] !== 'undefined') { |
266 | | - if (type === 'array') { |
267 | | - if (!Array.isArray(obj[property])) { |
268 | | - throw new Error(`View ${property} must be an array`) |
269 | | - } |
270 | | - // eslint-disable-next-line valid-typeof |
271 | | - } else if (typeof obj[property] !== type) { |
272 | | - throw new Error(`View ${property} must be a ${type}`) |
273 | | - } else if (type === 'object' && (obj[property] === null || Array.isArray(obj[property]))) { |
274 | | - throw new Error(`View ${property} must be an object`) |
| 245 | + // we cannot use `instanceof` here because if the Navigation and the Column class are loaded by different apps |
| 246 | + // (Navigation is set by files app and Column by a 3rd party app), |
| 247 | + // the `instanceof` check will fail even if the object has the correct shape because they are different classes in memory. |
| 248 | + view.columns.forEach(validateColumn) |
| 249 | + const columnIds = view.columns.reduce((set, column) => set.add(column.id), new Set<string>()) |
| 250 | + if (columnIds.size !== view.columns.length) { |
| 251 | + throw new Error('View columns must have unique ids') |
275 | 252 | } |
276 | 253 | } |
277 | 254 | } |
0 commit comments