Skip to content

Commit

Permalink
feat(select): new function
Browse files Browse the repository at this point in the history
  • Loading branch information
sandros94 committed May 31, 2024
1 parent 474e513 commit ee50c3e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 89 deletions.
6 changes: 2 additions & 4 deletions playground/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@ interface Product {
currency: string
}
const { sql } = useSurrealDB()
const { select } = useSurrealDB()
const search = ref('products')
const { data, error } = await sql<Product[]>('SELECT * FROM type::table($tb);', {
vars: { tb: search },
})
const { data, error } = await select<Product[]>(search)
error.value && console.error('error', error.value)
</script>
123 changes: 39 additions & 84 deletions src/runtime/composables/surreal-db.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import type { AsyncDataOptions, AsyncData, NuxtError } from 'nuxt/app'
import type { AsyncData } from 'nuxt/app'
import type { FetchError } from 'ofetch'
import { joinURL } from 'ufo'
import { hash } from 'ohash'

import type {
Overrides,
PickFrom,
KeysOf,
RpcRequest,
RpcResponse,
SurrealAsyncDataOptions,
SurrealRpcOptions,
} from '../types'

import type { MaybeRefOrGetter } from '#imports'
import {
computed,
createError,
toValue,
useAsyncData,
useNuxtApp,
useSurrealFetch,
useSurrealRPC,
Expand All @@ -26,90 +20,50 @@ import {
export function useSurrealDB(overrides?: Overrides) {
const { $surrealFetch, $surrealFetchOptionsOverride, $surrealRPC } = useNuxtApp()

// TODO: GET /export Exports all data for a specific Namespace and Database
// TODO: POST /import Imports data into a specific Namespace and Database
// TODO: authenticate [ token ]
// TODO: create [ thing, data ]
// TODO: delete [ thing ]
// TODO: info
// TODO: insert [ thing, data ]
// TODO: invalidate
// TODO: merge [ thing, data ]
// TODO: patch [ thing, patches, diff ]

async function items<T = any>(
record: MaybeRefOrGetter<string> | {
table: MaybeRefOrGetter<string>
id?: MaybeRefOrGetter<string>
},
options: AsyncDataOptions<T> & Overrides & {
key?: string
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
body?: RequestInit['body'] | Record<string, any>
} = {
...overrides,
method: 'GET',
key: undefined,
},
): Promise<AsyncData<PickFrom<T, KeysOf<T>> | null, NuxtError<unknown> | null>> {
const _record = toValue(record)
const {
key,
method,
body,
database,
token,
...opts
} = options
const { id, table } = typeof _record === 'string'
? { table: _record.split(':')[0], id: _record.split(':')[1] }
: _record
const _table = toValue(table)
const _key = computed(() => {
return key ?? 'Sur_' + hash(['surrealItems', toValue(_table), toValue(id || '')])
})

return useAsyncData<T>(_key.value, () => {
const endpoint = computed(() => joinURL('key', _table, toValue(id || '')))

if (!_table) {
throw createError({
statusCode: 400,
statusMessage: 'Table name is required',
})
}
if ((method === 'POST' || method === 'PUT' || method === 'PATCH') && !body) {
throw createError({
statusCode: 400,
statusMessage: 'Body is required for POST, PUT, and PATCH methods',
})
}

return $surrealFetch<T>(endpoint.value, {
...$surrealFetchOptionsOverride({
database,
token,
}),
method,
body,
})
}, opts)
}

// TODO: POST /ml/import Import a SurrealML model into a specific Namespace and Database
// TODO: GET /ml/export/:name/:version

// TODO: POST /signup Signs-up as a scope user to a specific scope
// TODO: POST /signin Signs-in as a root, namespace, database, or scope user

async function $sql<T = any>(
async function $query<T = any>(
sql: RpcRequest<T, 'query'>['params'][0],
opts?: Overrides & { vars: RpcRequest<T, 'query'>['params'][1] },
) {
const { vars, ...ovr } = opts || {}
return $surrealRPC<T>({ method: 'query', params: [sql, vars] }, ovr)
}

async function sql<T = any>(
async function query<T = any>(
sql: RpcRequest<T, 'query'>['params'][0],
options?: SurrealAsyncDataOptions<RpcResponse<T>> & { vars: RpcRequest<T, 'query'>['params'][1] },
options?: SurrealRpcOptions<T> & { vars: RpcRequest<T, 'query'>['params'][1] },
): Promise<AsyncData<RpcResponse<T> | null, FetchError<any> | null>> {
const { vars, ...opts } = options || {}
return useSurrealRPC<T>({ method: 'query', params: [sql, vars] }, opts)
}

async function $select<T = any>(
thing: RpcRequest<T, 'select'>['params'][0],
ovr?: Overrides,
) {
return $surrealRPC<T>({ method: 'select', params: [thing] }, ovr)
}
async function select<T = any>(
thing: MaybeRefOrGetter<RpcRequest<T, 'select'>['params'][0]>,
options?: SurrealRpcOptions<T>,
): Promise<AsyncData<RpcResponse<T> | null, FetchError<any> | null>> {
const params = computed(() => ([toValue(thing)]))
// @ts-expect-error TODO: better RPC type inference
return useSurrealRPC<T>({ method: 'select', params }, options)
}

// TODO: signin [ ... ]
// TODO: signup [ NS, DB, SC, ... ]
// TODO: update [ thing, data ]
// TODO: use [ ns, db ]

async function $version(ovr?: Overrides) {
return $surrealFetch('version', {
...$surrealFetchOptionsOverride(ovr || overrides),
Expand All @@ -122,11 +76,12 @@ export function useSurrealDB(overrides?: Overrides) {
}

return {
items,
$query: $sql,
query: sql,
$sql,
sql,
$query,
query,
$select,
select,
$sql: $query,
sql: query,
$version,
version,
}
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/composables/surreal-fetch.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { useFetch, useNuxtApp } from 'nuxt/app'
import { type MaybeRefOrGetter, ref } from 'vue'
import type { AsyncData } from 'nuxt/app'
import type { FetchError } from 'ofetch'

import type {
KeysOf,
PickFrom,
SurrealFetchOptions,
SurrealRpcOptions,
RpcRequest,
RpcResponse,
} from '../types'
import { type MaybeRefOrGetter, ref } from '#imports'

export function useSurrealFetch<T = any>(
endpoint: MaybeRefOrGetter<string>,
Expand Down

0 comments on commit ee50c3e

Please sign in to comment.