{"version":3,"sources":["../src/response.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { _default, coerce, int, maximum, minimum, object, optional, string } from 'zod/mini';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Empty = {};\nexport type EntityId = string | number;\nexport type Entity = { id: EntityId };\n\nexport type Response<T = never> = { data: T };\n\nexport type InitParams = { limit: number; parent?: string };\nexport type NextParams = { limit: number; parent?: string; next: string };\nexport type PrevParams = { limit: number; parent?: string; prev: string };\nexport type PageParams = { limit: number; prev?: string; next?: string };\nexport type ParentPageParams = { limit: number; parent: string; prev?: string; next?: string };\nexport type Page<T = never> = { data: T[]; paging: { next?: string; prev?: string } };\n\nexport function pageParamsSchema(max = 100, defaultLimit = 20) {\n  return object({\n    limit: _default(coerce.number().check(int(), minimum(1), maximum(max)), defaultLimit),\n    prev: optional(string()),\n    next: optional(string()),\n  });\n}\n\nexport const Cursor = {\n  of(\n    prev: bigint | number | string | undefined,\n    next: bigint | number | string | undefined\n  ): Page['paging'] {\n    return {\n      prev: prev ? this.encode(prev) : undefined,\n      next: next ? this.encode(next) : undefined,\n    };\n  },\n  empty(): Page['paging'] {\n    return { prev: undefined, next: undefined };\n  },\n  encode(id: bigint | number | string | undefined): string | undefined {\n    if (!id) return undefined;\n    return Buffer.from(id.toString(), 'utf-8').toString('base64');\n  },\n  decode<T extends 'bigint' | 'number' | 'string' = 'bigint'>(\n    token: string,\n    type: T = 'bigint' as T\n  ): T extends 'bigint' ? bigint : T extends 'number' ? number : string {\n    const value = Buffer.from(token, 'base64').toString('utf-8');\n    if (type === 'bigint')\n      return BigInt(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n    if (type === 'number')\n      return Number(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n    return value as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n  },\n};\n\nexport const initialPageParam: Page['paging'] = {};\n\nexport function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null {\n  return hasText(first.paging.prev) ? { prev: first.paging.prev } : null;\n}\n\nexport function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null {\n  return hasText(last.paging.next) ? { next: last.paging.next } : null;\n}\n\nexport type InfinitePageData<T> = {\n  pages: Array<Page<T>>;\n  pageParams: Array<Page['paging']>;\n};\n\nexport const Pages = {\n  flatten<T>(data: InfinitePageData<T>): T[] {\n    return data.pages.flatMap((page) => page.data);\n  },\n  dedupe<T extends Entity>(data: InfinitePageData<T>): T[] {\n    const seen = new Set<EntityId>();\n    const result: T[] = [];\n    for (const page of data.pages) {\n      for (const item of page.data) {\n        if (!seen.has(item.id)) {\n          seen.add(item.id);\n          result.push(item);\n        }\n      }\n    }\n    return result;\n  },\n  prepend<T>(item: T) {\n    return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n      if (!data) return data;\n      const [first, ...rest] = data.pages;\n      if (!first) return { ...data, pages: [{ data: [item], paging: {} }] };\n      return { ...data, pages: [{ ...first, data: [item, ...first.data] }, ...rest] };\n    };\n  },\n  append<T>(item: T) {\n    return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n      if (!data) return data;\n      const pages = data.pages;\n      const last = pages[pages.length - 1];\n      if (!last) return { ...data, pages: [{ data: [item], paging: {} }] };\n      return { ...data, pages: [...pages.slice(0, -1), { ...last, data: [...last.data, item] }] };\n    };\n  },\n  update<T>(updater: T, predicate: (item: T) => boolean) {\n    return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n      if (!data) return data;\n      return {\n        ...data,\n        pages: data.pages.map((page) => ({\n          ...page,\n          data: page.data.map((item) => (predicate(item) ? updater : item)),\n        })),\n      };\n    };\n  },\n  updateById<T extends Entity>(updated: T) {\n    return this.update<T>(updated, (item) => item.id === updated.id);\n  },\n  remove<T>(predicate: (item: T) => boolean) {\n    return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n      if (!data) return data;\n      return {\n        ...data,\n        pages: data.pages.map((page) => ({\n          ...page,\n          data: page.data.filter((item) => !predicate(item)),\n        })),\n      };\n    };\n  },\n  removeById<T extends Entity>(id: EntityId) {\n    return this.remove<T>((item) => item.id === id);\n  },\n};\n\nexport const Items = {\n  push<T>(newItems: T[]) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return newItems;\n      return [...data, ...newItems];\n    };\n  },\n  unshift<T>(newItems: T[]) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return newItems;\n      return [...newItems, ...data];\n    };\n  },\n  pushAndDedupe<T extends Entity>(newItems: T[]) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return newItems;\n      const seen = new Set<EntityId>();\n      const result: T[] = [];\n      for (const item of data) {\n        if (!seen.has(item.id)) {\n          seen.add(item.id);\n          result.push(item);\n        }\n      }\n      for (const item of newItems) {\n        if (!seen.has(item.id)) {\n          seen.add(item.id);\n          result.push(item);\n        }\n      }\n      return result;\n    };\n  },\n  unshiftAndDedupe<T extends Entity>(newItems: T[]) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return newItems;\n      const seen = new Set<EntityId>();\n      const result: T[] = [];\n      for (const item of newItems) {\n        if (!seen.has(item.id)) {\n          seen.add(item.id);\n          result.push(item);\n        }\n      }\n      for (const item of data) {\n        if (!seen.has(item.id)) {\n          seen.add(item.id);\n          result.push(item);\n        }\n      }\n      return result;\n    };\n  },\n  update<T>(updater: T, predicate: (item: T) => boolean) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return data;\n      return data.map((item) => (predicate(item) ? updater : item));\n    };\n  },\n  updateById<T extends Entity>(updated: T) {\n    return this.update<T>(updated, (item) => item.id === updated.id);\n  },\n  remove<T>(predicate: (item: T) => boolean) {\n    return (data: T[] | undefined): T[] | undefined => {\n      if (!data) return data;\n      return data.filter((item) => !predicate(item));\n    };\n  },\n  removeById<T extends Entity>(id: EntityId) {\n    return this.remove<T>((item) => item.id === id);\n  },\n};\n"],"mappings":"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","names":[]}