sanity-typed icon indicating copy to clipboard operation
sanity-typed copied to clipboard

Issue with null value in referenced document

Open trulymittal opened this issue 10 months ago • 2 comments

  1. Though I am getting the correct fields in the referenced document, but all the values are null type instead being string | nulltype.
  2. Using groq asimport groq from 'groq' using the GROQ tagged template literal, I am getting a response as Promise<never> instead of being typed, Is this the intended behavior

trulymittal avatar Mar 25 '24 17:03 trulymittal

  1. Can you provide the schema or query for what you're talking about?
  2. I hadn't even considered the groq template literal, will need to do that!

saiichihashimoto avatar Mar 25 '24 18:03 saiichihashimoto

Sure here it is:

This is the site settings schema

import { Settings2Icon } from 'lucide-react'
// import { defineField, defineType } from 'sanity'
import { defineField, defineType } from '@sanity-typed/types'

export const siteSettingsType = defineType({
  name: 'siteSettings',
  title: 'Site settings',
  type: 'document',
  icon: Settings2Icon,
  groups: [
    {
      name: 'general',
      title: 'General',
    },
    {
      name: 'seo',
      title: 'Global SEO',
    },
    {
      name: 'assistant',
      title: 'AI assistant',
    },
  ],
  fields: [
    defineField({
      name: 'title',
      type: 'string',
      validation: (Rule) => Rule.required(),
    }),
    defineField({
      name: 'description',
      type: 'text',
      rows: 5,
    }),
    defineField({
      title: 'AI assistant',
      name: 'assistant',
      type: 'reference',
      to: [{ type: 'assistant' as const }],
      group: ['assistant'],
    }),
    defineField({
      title: 'SEO Title',
      name: 'seoTitle',
      type: 'string',
      group: 'seo',
    }),
    defineField({
      title: 'SEO Meta description',
      name: 'seoMetaDescription',
      type: 'text',
      rows: 5,
      group: 'seo',
    }),
    defineField({
      title: 'SEO Meta image',
      name: 'seoMetaImage',
      type: 'image',
      options: {
        hotspot: true,
      },
      group: 'seo',
    }),
  ],
  preview: {
    select: {
      title: 'title',
      subtitle: 'instructions',
    },
  },
})

the assistant schema is

import { BotIcon } from 'lucide-react'
// import { defineField, defineType } from 'sanity'
import { defineField, defineType } from '@sanity-typed/types'

export const assistantType = defineType({
  name: 'assistant',
  title: 'AI Assistant',
  type: 'document',
  icon: BotIcon,
  groups: [
    {
      name: 'advanced',
      title: 'Advanced',
    },
    {
      name: 'persona',
      title: 'Persona',
    },
  ],
  fields: [
    defineField({
      name: 'title',
      type: 'string',
    }),
    defineField({
      name: 'model',
      type: 'string',
      options: {
        list: [
          { title: 'GPT-3.5-TURBO', value: 'gpt-3.5-turbo' },
          { title: 'GPT-4-TURBO-PREVIEW', value: 'gpt-4-turbo-preview' },
          { title: 'GPT-4', value: 'gpt-4' },
        ],
      },
      initialValue: 'gpt-3.5-turbo',
    }),
    defineField({
      name: 'instructions',
      type: 'text',
      rows: 5,
      group: 'persona',
    }),
    defineField({
      name: 'temperature',
      type: 'number',
      initialValue: 0.2,
      validation: (rule) => rule.required().min(0).max(1).precision(1),
      group: 'advanced',
    }),
    {
      title: 'Functions',
      name: 'functions',
      type: 'array',
      of: [
        {
          type: 'string',
          options: {
            list: [
              { title: 'Google places', value: 'google-places-api' },
              { title: 'Google Directions', value: 'google-directions-api' },
              { title: 'Tavily search', value: 'tavily-search' },
              { title: 'Exa search', value: 'exa-search' },
              { title: 'Search API', value: 'search-api' }
            ],
          },
        },
      ],
      group: 'advanced',
    },
  ],
  preview: {
    select: {
      title: 'title',
      subtitle: 'model',
    },
  },
})

The query I am making is

export const ASSISTANT_QUERY = `*[_type == "siteSettings" && _id == "siteSettings"][0]{
  assistant -> {
    temperature,
    model,
    functions,
    instructions
  }
}`

Client defined as

import { createClient } from '@sanity-typed/client'

import { apiVersion, dataset, projectId } from '~/sanity/projectDetails'

import type { SanityValues } from 'sanity.config'

export const client = createClient<SanityValues>({
  projectId,
  dataset,
  apiVersion,
  useCdn: true,
  perspective: 'published',
})

Sanity.config.ts

import { visionTool } from '@sanity/vision'
// import { defineConfig } from 'sanity'
import { InferSchemaValues, defineConfig } from '@sanity-typed/types'
import { structureTool } from 'sanity/structure'

import { projectDetails } from '~/sanity/projectDetails'
import schema from '~/sanity/schema'
import { defaultDocumentNode, structure } from '~/sanity/structure'

export const config = defineConfig({
  ...projectDetails(),
  name: 'sanity-remix',
  title: 'Sanity Remix',
  plugins: [
    structureTool({
      structure: structure,
      defaultDocumentNode: defaultDocumentNode,
    }),
    visionTool(),
  ],
  basePath: `/studio`,
  schema: {
    types: schema,
  },
})

export type SanityValues = InferSchemaValues<typeof config>

Now when making the query as:

import { client } from '~/sanity/client'
import { ASSISTANT_QUERY } from '~/sanity/queries'

export const getCurrentAssistant = () => client.fetch(ASSISTANT_QUERY)

The return type is defined as:

const getCurrentAssistant: () => Promise<{
    assistant: {
        temperature: null;
        model: null;
        functions: null;
        instructions: null;
    };
}>

Which is not the correct return type, though type definitions are there, but individual fields are not...

For 2, when making the query as

import groq from 'groq'

export const ASSISTANT_QUERY = groq`*[_type == "siteSettings" && _id == "siteSettings"][0]{
  assistant -> {
    temperature,
    model,
    functions,
    instructions
  }
}`

The return type is not even typed, as you said you haven't factored this in, but just for clarity, the return type is:

const getCurrentAssistant: () => Promise<never>

trulymittal avatar Mar 26 '24 12:03 trulymittal