@kiki.im.dev/zenstack-fetch
Version:
Generate fetch function from ZModel schema file of ZenStack with ofetch
196 lines (163 loc) • 4.66 kB
text/typescript
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import type { Prisma } from "@zenstackhq/runtime/models"
import { type PrismaClient } from "@zenstackhq/runtime"
import { deserialize } from "superjson"
import { type MaybeRef, ref, unref } from "vue"
type Any = Record<string, unknown>
export type Model = Exclude<keyof PrismaClient, `$${string}` | symbol>
type Operation<M extends Model> = keyof PrismaClient[M] & PrismaOperation
export type PrismaInput<
M extends Model,
O extends Operation<M>,
S,
> = Prisma.Exact<S, Prisma.Args<PrismaClient[M], O>>
type UsePrismaArgs<M extends Model, O extends Operation<M>, S> = {
model: M
operation: O
input?: MaybeRef<Prisma.Exact<S, Prisma.Args<PrismaClient[M], O>>>
}
export type Sort<ColumnT> = {
column: keyof ColumnT
direction: ColumnT[keyof ColumnT]
}
export const usePrisma = async <M extends Model, O extends Operation<M>, S>(
args: UsePrismaArgs<M, O, S>
) => {
const { model, operation, input = {} } = args
const data = ref(undefined as Prisma.Result<PrismaClient[M], S, O>)
const execute = async () => {
const unreffedInput = unref(input)
let method: "GET" | "POST" | "PUT" | "DELETE" = "GET"
if (
operation === "create" ||
operation === "createMany" ||
operation === "upsert"
)
method = "POST"
else if (operation === "update" || operation === "updateMany")
method = "PUT"
else if (operation === "delete" || operation === "deleteMany")
method = "DELETE"
let query: { q: unknown } | undefined = undefined
if (unreffedInput) {
query = {
q: unreffedInput,
}
}
let body
if (operation === "create") {
body = {
data: (unreffedInput as Any)?.data,
}
}
if (operation === "update" || operation === "updateMany") {
body = {
data: (unreffedInput as Any)?.data,
where: (unreffedInput as Any)?.where,
}
}
if (operation === "upsert") {
body = {
create: (unreffedInput as Any)?.create,
update: (unreffedInput as Any)?.update,
where: (unreffedInput as Any)?.where,
}
}
if (operation === "delete" || operation === "deleteMany") {
body = {
where: (unreffedInput as Any)?.where,
}
}
const headers = useRequestHeaders()
const error = ref(null)
const fetch = await $fetch(`/api/model/${model}/${operation}`, {
method,
query,
body,
headers,
}).catch((e) => (error.value = e))
if (error.value) throw error.value
// const response = fetch.value
const response = fetch
const { data: json, meta } = response
let _data = json
if (meta) _data = deserialize({ json, meta: meta.serialization })
data.value = _data
// return response as { data: typeof _data }
return data.value
}
return await execute()
}
export const defineTake = (take: MaybeRef<number | undefined>) =>
unref(take) ? Number(unref(take)) : undefined
export const defineSkip = ({
perPage,
page,
}: {
perPage: MaybeRef<number | undefined>
page: MaybeRef<number | undefined>
}) => {
const _perPage = unref(perPage)
const _page = unref(page)
if (!_page) return undefined
const skip = Number((_perPage || 10) * (_page - 1))
return skip
}
export const defineOrderBy = <T>(sort: MaybeRef<Sort<T> | undefined>) => {
const _sort = unref(sort)
if (!_sort) return undefined
const orderBy = dotStringToObject(
_sort.column as string,
_sort.direction
) as T
return orderBy
// return {
// [_sort.column]: _sort.direction,
// }
}
export const defineWhere = <T>(where: MaybeRef<T | undefined>) => {
const _where = unref(where)
if (!_where || !Object.keys(_where as unknown[]).length) return undefined
return _where
}
function dotStringToObject(strings: string, data: unknown): unknown {
const keys = strings.split(".").reverse()
let lastKey = ""
const current: Any = {}
keys.map((key) => {
if (!lastKey) {
current[key] = data
} else {
current[key] = { ...current }
delete current[lastKey]
}
lastKey = key
})
return current
}
export const operations = [
"findFirst",
"findFirstOrThrow",
"findUnique",
"findUniqueOrThrow",
"findMany",
"create",
"createMany",
"update",
"updateMany",
"upsert",
"delete",
"deleteMany",
"aggregate",
"count",
"groupBy",
// "$queryRaw",
// "$executeRaw",
// "$queryRawUnsafe",
// "$executeRawUnsafe",
// "findRaw",
// "aggregateRaw",
// "$runCommandRaw",
] as const
export type PrismaOperation = (typeof operations)[number]