groqd
groqd copied to clipboard
No longer possible to get resultSourceMap from sanity client.
Is there an existing issue for this?
- [x] I have searched the existing issues
Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Code Sandbox link
No response
Bug report
When enabling visual editing you have to serialize the data within your html markup. It seems that when using the "makeSafeQueryRunner" function, there is no way to allow the function to return anything other than the actual data. This makes it impossible to use with the visual editor.
Maybe additional configuration could be added to allow for this?
Can you give mea code sample, and a link to the relevant docs, so i can understand this feature better?
Hey @scottrippey , sorry for the delay here! I don't know why I forgot to include the referrence and provide more context!
I'm just reading based off of the normal sanity integration tutorial for an astro project.
One thing you cannot do with the existing groqd is set filterResponse to false and receive the source map.
Normal integration example:
// load-query.ts
import {type QueryParams} from 'sanity'
import {sanityClient} from 'sanity:client'
const visualEditingEnabled = import.meta.env.PUBLIC_SANITY_VISUAL_EDITING_ENABLED === 'true'
const token = import.meta.env.SANITY_API_READ_TOKEN
export async function loadQuery<QueryResponse>({
query,
params,
}: {
query: string
params?: QueryParams
}) {
if (visualEditingEnabled && !token) {
throw new Error(
'The `SANITY_API_READ_TOKEN` environment variable is required during Visual Editing.',
)
}
const perspective = visualEditingEnabled ? 'drafts' : 'published'
const {result, resultSourceMap} = await sanityClient.fetch<QueryResponse>(query, params ?? {}, {
filterResponse: false,
perspective,
resultSourceMap: visualEditingEnabled ? 'withKeyArraySelector' : false,
stega: visualEditingEnabled,
...(visualEditingEnabled ? {token} : {}),
useCdn: !visualEditingEnabled,
})
return {
data: result,
sourceMap: resultSourceMap,
perspective,
}
}
If you try to do something similar with the client groqd you'll get an error becausee the makeSafeQueryRunner is specifically looking for the query data to be returned.
import type * as SanityTypes from "./sanity.types.ts";
import { sanityClient } from "sanity:client";
import { createGroqBuilder, makeSafeQueryRunner } from "groqd";
const visualEditingEnabled =
import.meta.env.PUBLIC_SANITY_VISUAL_EDITING_ENABLED === "true";
const token = import.meta.env.SANITY_API_READ_TOKEN;
const perspective = visualEditingEnabled ? "drafts" : "published";
// Throws an error because it's expecting only the data to be returned.
export const runQuery = makeSafeQueryRunner(async (query, { parameters }) => {
if (visualEditingEnabled && !token) {
throw new Error(
"The `SANITY_API_READ_TOKEN` environment variable is required during Visual Editing.",
);
}
const {result, resultSourceMap} = await sanityClient.fetch(query, parameters, {
filterResponse: false,
perspective,
resultSourceMap: visualEditingEnabled ? "withKeyArraySelector" : false,
stega: visualEditingEnabled,
...(visualEditingEnabled ? { token } : {}),
useCdn: !visualEditingEnabled,
});
return {
data: result,
sourceMap: resultSourceMap,
perspective,
}
});
type SchemaConfig = {
schemaTypes: SanityTypes.AllSanitySchemaTypes;
referenceSymbol: typeof SanityTypes.internalGroqTypeReferenceTo;
};
export const q = createGroqBuilder<SchemaConfig>({});
I hope this helps provide additional context, thanks for looking into this, I really appreciate any assistance or guidance you can provide :) !
Thank you for the context!
Ironically, @BrianWalters had this same problem 2 years ago and I just came across his workaround.
I would be happy to create an alternative to makeSafeQueryRunner, that allows arbitrary return values. The hardest part at this point is coming up with a name! Any suggestions?
Names are always the hardest part 😆 !
Here's a list of names:
makeSafeQueryWrappermakeSafeQueryWithContext
I forgot to send this message yesterday!
I've been playing around with some possible syntax, and I've come to a few options. Open for feedback.
First let's assume that the runQuery should allow for extra inputs (eg. tags or draftMode).
type ExtraInputs = { tags: string[], perspective: string };
Let's also assume that we can include extra fields in the output (eg. resultSourceMap or more).
type ExtraOutputs = { resultSourceMap: unknown };
So here's my proposed syntax. I'd like to continue supporting a "just the results" method, in addition to a "results with the metadata". And I can't think of a good way to do this within a single function, so I'm proposing 2 functions:
createQueryRunnerto replacemakeSafeQueryRunner... it's the exact same, just renamed.createQueryRunnerExtendedto support the "with metadata" approach:
const runQuery = createQueryRunnerExtended<ExtraInputs, ExtraOutputs>((query, inputs) => {
const {
parameters, // you'll ALWAYS get the `parameters` as an input, in addition to ExtraInputs
tags,
perspective,
} = inputs;
// fetch the data as normal:
const { result, resultSourceMap } = await sanityFetch(query, { params: parameters, tags, perspective });
return {
result, // you must ALWAYS return the `result`, in addition to the ExtraOutputs
resultSourceMap,
};
})
The main advantage of these functions is:
- Automatically calls "parse"
- Strongly-typed
parametersfield -- it's optional if there are no params, it's required if there are. - Handles all the types for you ... you only need to specify your extra inputs / outputs.
Open for feedback!
I absolutely love this idea 😄 ! I can't see any negatives with how createQueryRunnerExtended is meant to function! My only thought for the naming of createQueryRunnerExtended is the naming, maybe it could be createExtendedQueryRunner?