import _ from 'lodash' import { type Model, type ModelField, type RequestConfig, type CreateApiOptions, type CreateApiResourceOption, } from './interfaces' const isFieldEqual = (key: string, item: Model, field: ModelField) => { const itemField = item[key] if (itemField === undefined) return true if (typeof itemField === 'string' && typeof field === 'string') { return itemField.indexOf(field) > -1 } if ( typeof itemField === 'object' && 'id' in itemField && typeof field === 'object' && 'id' in field ) return itemField.id === field.id return itemField === field } export class Repository { key!: string isEnum = false models: Model[] = [] customFilter?: (i: any, params: RequestConfig['params']) => boolean constructor(key: string, options: CreateApiResourceOption) { this.key = key this.isEnum = Boolean(options.enum) this.customFilter = options.customFilter this.loadFromStorage() } loadFromStorage() { const item = localStorage.getItem(`ark-ui-stubs-storage-${this.key}`) if (item) this.models = JSON.parse(item) } saveToStorage() { localStorage.setItem(`ark-ui-stubs-storage-${this.key}`, JSON.stringify(this.models)) } count() { return this.models.length } find(id: number) { return this.models.find((model) => model.id === id) } add(model: Model) { this.models.push(model) this.saveToStorage() } update(model: Model) { const oldModel = this.find(model.id) if (oldModel) { this.models[this.models.indexOf(oldModel)] = model this.saveToStorage() } } delete(id: number) { const model = this.find(id) if (model) { this.models.splice(this.models.indexOf(model), 1) this.saveToStorage() } } getRandomItem() { return this.models[Math.floor(Math.random() * this.models.length)] } select(params: NonNullable, options: CreateApiOptions) { const items = this.models let sortField: string | undefined = params[options.sortFieldKey] as string const excludeConfigKeys: string[] = [ options.requestLimitKey, options.requestOffsetKey, options.requestPageKey, options.requestPerPageKey, options.sortFieldKey, ] const paramsWithoutConfig = Object .keys(params) .filter((key) => !excludeConfigKeys.includes(key)) let filteredItems: Model[] = paramsWithoutConfig.reduce((acc, key) => { const param = params[key] if (Array.isArray(param)) { return param.reduce((subAcc, value) => subAcc.filter((item) => isFieldEqual(key, item, value)), acc) } return acc.filter((item) => isFieldEqual(key, item, param)) }, items) if (this.customFilter) { filteredItems = filteredItems.filter((i: any) => (this.customFilter ? this.customFilter(i, params) : true)) } if (sortField) { const sortType: 'asc' | 'desc' = sortField.indexOf('-') > -1 ? 'desc' : 'asc' if (sortType === 'desc') { sortField = sortField.substring(1) } filteredItems = _.orderBy(filteredItems, (item) => { if (!sortField) return undefined if (typeof item[sortField] === 'object') { return item[sortField].id } return item[sortField] }, [sortType]) } return filteredItems } distinct(keyField: string, params: NonNullable, options: CreateApiOptions) { return Array.from(new Set(this.select(params, options).map((item) => item[keyField]))) } }