@devite/nuxt-sanity 2.4.3 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -3
- package/dist/runtime/client/DefaultSanityClient.d.ts +2 -2
- package/dist/runtime/client/DefaultSanityClient.js +6 -1
- package/dist/runtime/client/MinimalSanityClient.d.ts +1 -1
- package/dist/runtime/client/MinimalSanityClient.js +10 -5
- package/dist/runtime/client/SanityClient.d.ts +3 -2
- package/dist/runtime/components/SanityPage.vue +1 -2
- package/dist/runtime/composables/{useSanityQuery.d.ts → query.d.ts} +8 -7
- package/dist/runtime/composables/query.js +56 -0
- package/dist/runtime/composables/useSanityLiveMode.d.ts +1 -1
- package/dist/runtime/composables/useSanityLiveMode.js +6 -10
- package/dist/runtime/plugins/visual-editing.js +2 -2
- package/dist/runtime/server/routes/cache/asset.js +1 -1
- package/dist/runtime/server/routes/cache/query.d.ts +1 -1
- package/dist/runtime/server/routes/cache/query.js +3 -2
- package/dist/runtime/server/routes/cache/webhook.js +3 -2
- package/dist/runtime/server/utils/useSanityClient.d.ts +3 -2
- package/dist/runtime/server/utils/useSanityClient.js +16 -13
- package/dist/runtime/utils/default/fetchSanityData.d.ts +5 -0
- package/dist/runtime/utils/default/fetchSanityData.js +5 -0
- package/dist/runtime/utils/resolveImageAssetById.js +5 -2
- package/dist/runtime/utils/resolveInternalLink.js +5 -2
- package/dist/runtime/utils/useSanityClient.d.ts +3 -1
- package/dist/runtime/utils/useSanityClient.js +12 -7
- package/dist/runtime/utils/visualEditing/fetchSanityData.d.ts +5 -0
- package/dist/runtime/utils/visualEditing/fetchSanityData.js +21 -0
- package/dist/runtime/utils/visualEditing/subscribeToChanges.d.ts +5 -0
- package/dist/runtime/utils/visualEditing/subscribeToChanges.js +19 -0
- package/package.json +2 -1
- package/dist/runtime/composables/useLazySanityQuery.d.ts +0 -4
- package/dist/runtime/composables/useLazySanityQuery.js +0 -4
- package/dist/runtime/composables/useSanityQuery.js +0 -69
- package/dist/runtime/utils/getOrCreateSanityClient.d.ts +0 -4
- package/dist/runtime/utils/getOrCreateSanityClient.js +0 -15
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { defineNuxtModule, createResolver, addPlugin, addServerHandler, addImpor
|
|
|
3
3
|
import defu from 'defu';
|
|
4
4
|
|
|
5
5
|
const name = "@devite/nuxt-sanity";
|
|
6
|
-
const version = "2.
|
|
6
|
+
const version = "2.5.0";
|
|
7
7
|
|
|
8
8
|
const CONFIG_KEY = "sanity";
|
|
9
9
|
const module = defineNuxtModule({
|
|
@@ -141,8 +141,8 @@ const module = defineNuxtModule({
|
|
|
141
141
|
addImports(
|
|
142
142
|
[
|
|
143
143
|
// composables
|
|
144
|
-
{ name: "useSanityQuery", from: resolve("runtime/composables/
|
|
145
|
-
{ name: "useLazySanityQuery", from: resolve("runtime/composables/
|
|
144
|
+
{ name: "useSanityQuery", from: resolve("runtime/composables/query") },
|
|
145
|
+
{ name: "useLazySanityQuery", from: resolve("runtime/composables/query") },
|
|
146
146
|
// helper methods
|
|
147
147
|
{ name: "groq", from: resolve("runtime/utils/groq") },
|
|
148
148
|
{ name: "resolveImageAssetById", from: resolve("runtime/utils/resolveImageAssetById") },
|
|
@@ -6,9 +6,9 @@ declare class DefaultSanityClient extends SanityClient {
|
|
|
6
6
|
readonly client: SanityClientType;
|
|
7
7
|
queryStore: QueryStore | null;
|
|
8
8
|
constructor(config: ModuleOptions);
|
|
9
|
-
fetch<T
|
|
9
|
+
fetch<T>(query: string, params: QueryParams, options?: {
|
|
10
10
|
perspective?: ClientPerspective;
|
|
11
|
-
}): Promise<T>;
|
|
11
|
+
}): Promise<T | null>;
|
|
12
12
|
createQueryStore(tag?: string): void;
|
|
13
13
|
clone(): DefaultSanityClient;
|
|
14
14
|
}
|
|
@@ -11,7 +11,12 @@ class DefaultSanityClient extends SanityClient {
|
|
|
11
11
|
this.client = createClient(config);
|
|
12
12
|
}
|
|
13
13
|
async fetch(query, params, options) {
|
|
14
|
-
|
|
14
|
+
try {
|
|
15
|
+
return await this.client.fetch(query, params, options);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error("Failed to fetch data from Sanity:", error);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
21
|
createQueryStore(tag) {
|
|
17
22
|
const queryStore = createCoreQueryStore({
|
|
@@ -9,7 +9,7 @@ declare class MinimalSanityClient extends SanityClient {
|
|
|
9
9
|
private toQueryString;
|
|
10
10
|
fetch<T>(query: string, params: QueryParams, _options?: {
|
|
11
11
|
perspective?: ClientPerspective;
|
|
12
|
-
}): Promise<T>;
|
|
12
|
+
}): Promise<T | null>;
|
|
13
13
|
clone(): MinimalSanityClient;
|
|
14
14
|
}
|
|
15
15
|
export default MinimalSanityClient;
|
|
@@ -41,11 +41,16 @@ class MinimalSanityClient extends SanityClient {
|
|
|
41
41
|
const useCache = minimalClientConfig.cachingEnabled && isEligibleForGetRequest;
|
|
42
42
|
const cacheBaseUrl = import.meta.client ? minimalClientConfig.cacheClientBaseUrl : minimalClientConfig.cacheServerBaseUrl;
|
|
43
43
|
const requestUrl = useCache && cacheBaseUrl ? cacheBaseUrl + minimalClientConfig.queryEndpoint : `https://${this.config.projectId}.${this.config.useCdn && isEligibleForGetRequest ? API_CDN_HOST : API_HOST}${this.queryPath}`;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
try {
|
|
45
|
+
return (await $fetch(requestUrl + queryString, {
|
|
46
|
+
...this.fetchOptions,
|
|
47
|
+
method: isEligibleForGetRequest ? "GET" : "POST",
|
|
48
|
+
body: !isEligibleForGetRequest ? { query, params } : void 0
|
|
49
|
+
})).result;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("Failed to fetch data from Sanity:", error);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
clone() {
|
|
51
56
|
return new MinimalSanityClient({
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
|
|
2
2
|
import type { ModuleOptions } from '@devite/nuxt-sanity';
|
|
3
|
+
export type SanityClientType = 'minimal' | 'default';
|
|
3
4
|
export default abstract class SanityClient {
|
|
4
5
|
config: ModuleOptions;
|
|
5
6
|
sourceMap: ContentSourceMap | undefined;
|
|
6
7
|
protected constructor(config: ModuleOptions);
|
|
7
|
-
abstract fetch<T
|
|
8
|
+
abstract fetch<T>(query: string, params: QueryParams, options?: {
|
|
8
9
|
perspective?: ClientPerspective;
|
|
9
|
-
}): Promise<T>;
|
|
10
|
+
}): Promise<T | null>;
|
|
10
11
|
}
|
|
@@ -14,9 +14,8 @@ import type { ImageAsset } from '@sanity/types'
|
|
|
14
14
|
import type { GlobalSEO, Home, NotFound, Page } from '@devite/nuxt-sanity'
|
|
15
15
|
import { setResponseStatus } from 'h3'
|
|
16
16
|
import { IMAGE_WITHOUT_PREVIEW_PROJECTION } from '../utils/projections'
|
|
17
|
-
import { useSanityQuery } from '../composables/useSanityQuery'
|
|
18
17
|
import { groq } from '../utils/groq'
|
|
19
|
-
import { useHead, useRoute, useRuntimeConfig,
|
|
18
|
+
import { useHead, useRequestEvent, useRoute, useRuntimeConfig, useSanityQuery, useSeoMeta } from '#imports'
|
|
20
19
|
|
|
21
20
|
const path = useRoute().path
|
|
22
21
|
const groqFilter = path === '/' ? '_type == "home"' : `_type == "page" && slug.current == $slug`
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import type { AsyncDataOptions, AsyncDataRequestStatus } from 'nuxt/app';
|
|
1
2
|
import type { ContentSourceMap, QueryParams } from '@sanity/client';
|
|
2
3
|
import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
|
|
3
|
-
import type { AsyncDataOptions, AsyncDataRequestStatus } from 'nuxt/app';
|
|
4
4
|
import { type Ref } from 'vue';
|
|
5
|
+
export interface UseSanityQueryOptions<T> extends AsyncDataOptions<T> {
|
|
6
|
+
client?: 'default' | 'minimal';
|
|
7
|
+
perspective?: 'previewDrafts' | 'published' | 'raw';
|
|
8
|
+
}
|
|
5
9
|
export interface SanityQueryResponse<T> {
|
|
6
10
|
data: T;
|
|
7
11
|
sourceMap?: ContentSourceMap;
|
|
8
12
|
encodeDataAttribute?: EncodeDataAttributeFunction;
|
|
9
13
|
}
|
|
14
|
+
export type AsyncSanityData<T, E> = _AsyncSanityData<T, E> & Promise<_AsyncSanityData<T, E>>;
|
|
10
15
|
interface AsyncDataExecuteOptions {
|
|
11
16
|
_initial?: boolean;
|
|
12
17
|
dedupe?: boolean;
|
|
@@ -21,10 +26,6 @@ export interface _AsyncSanityData<T, E> {
|
|
|
21
26
|
error: Ref<E | null>;
|
|
22
27
|
status: Ref<AsyncDataRequestStatus>;
|
|
23
28
|
}
|
|
24
|
-
export
|
|
25
|
-
export
|
|
26
|
-
client?: 'default' | 'minimal';
|
|
27
|
-
perspective?: 'previewDrafts' | 'published' | 'raw';
|
|
28
|
-
}
|
|
29
|
-
export declare const useSanityQuery: <T = unknown, E = Error>(query: string, _params?: QueryParams, _options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>, lazy?: boolean) => AsyncSanityData<T | null, E>;
|
|
29
|
+
export declare function useLazySanityQuery<T = unknown, E = Error>(query: string, params?: QueryParams, options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>): AsyncSanityData<T | null, E>;
|
|
30
|
+
export declare function useSanityQuery<T = unknown, E = Error>(query: string, _params?: QueryParams, options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>, lazy?: boolean): AsyncSanityData<T | null, E>;
|
|
30
31
|
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { hash } from "ohash";
|
|
2
|
+
import { useAsyncData, useLazyAsyncData } from "nuxt/app";
|
|
3
|
+
import { reactive, ref } from "vue";
|
|
4
|
+
import defu from "defu";
|
|
5
|
+
import useSanityClient from "../utils/useSanityClient.js";
|
|
6
|
+
import useServerSanityClient from "../server/utils/useSanityClient.js";
|
|
7
|
+
import { useSanityVisualEditingState } from "./useSanityVisualEditingState.js";
|
|
8
|
+
import { useRuntimeConfig } from "#imports";
|
|
9
|
+
export function useLazySanityQuery(query, params = {}, options = {}) {
|
|
10
|
+
return useSanityQuery(query, params, options, true);
|
|
11
|
+
}
|
|
12
|
+
export function useSanityQuery(query, _params = {}, options = {}, lazy = false) {
|
|
13
|
+
const $config = useRuntimeConfig();
|
|
14
|
+
const sanityConfig = defu(import.meta.server ? $config.sanity : {}, $config.public.sanity);
|
|
15
|
+
const visualEditingEnabled = useSanityVisualEditingState().enabled;
|
|
16
|
+
const clientType = visualEditingEnabled ? "default" : options.client || (sanityConfig.minimalClient ? "minimal" : "default");
|
|
17
|
+
const perspective = options.perspective || (visualEditingEnabled ? "previewDrafts" : "published");
|
|
18
|
+
const reactiveParams = _params ? reactive(_params) : void 0;
|
|
19
|
+
if (reactiveParams) {
|
|
20
|
+
options.watch ||= [];
|
|
21
|
+
options.watch.push(reactiveParams);
|
|
22
|
+
}
|
|
23
|
+
const data = ref(null);
|
|
24
|
+
const sourceMap = ref(null);
|
|
25
|
+
const encodeDataAttribute = ref(() => {
|
|
26
|
+
});
|
|
27
|
+
function updateRefs(resultData, resultSourceMap, resultEncodeDataAttribute) {
|
|
28
|
+
data.value = resultData;
|
|
29
|
+
sourceMap.value = resultSourceMap || null;
|
|
30
|
+
if (resultEncodeDataAttribute) encodeDataAttribute.value = resultEncodeDataAttribute;
|
|
31
|
+
}
|
|
32
|
+
const fetchFunc = () => new Promise((resolve) => {
|
|
33
|
+
(visualEditingEnabled ? import("../utils/visualEditing/fetchSanityData.ts") : import("../utils/default/fetchSanityData.ts")).then(async ({ fetchSanityData }) => {
|
|
34
|
+
const client = import.meta.server ? useServerSanityClient(clientType, sanityConfig) : await useSanityClient(visualEditingEnabled, clientType, sanityConfig);
|
|
35
|
+
function onDataUpdate(resultData, resultSourceMap, resultEncodeDataAttribute) {
|
|
36
|
+
if (resultEncodeDataAttribute)
|
|
37
|
+
encodeDataAttribute.value = resultEncodeDataAttribute;
|
|
38
|
+
resolve({ data: resultData, sourceMap: resultSourceMap });
|
|
39
|
+
}
|
|
40
|
+
const fetchSanityDataFunc = fetchSanityData;
|
|
41
|
+
fetchSanityDataFunc(query, reactiveParams, client, perspective, onDataUpdate);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
const key = "sanity-" + hash(query + (reactiveParams ? JSON.stringify(reactiveParams) : ""));
|
|
45
|
+
const pendingData = lazy ? useLazyAsyncData(key, fetchFunc, options) : useAsyncData(key, fetchFunc, options);
|
|
46
|
+
if (visualEditingEnabled && import.meta.client) {
|
|
47
|
+
import("../utils/visualEditing/subscribeToChanges.ts").then(async ({ subscribeToChanges }) => {
|
|
48
|
+
const client = await useSanityClient(visualEditingEnabled, clientType, sanityConfig);
|
|
49
|
+
subscribeToChanges(query, reactiveParams, client, updateRefs);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return Object.assign(new Promise((resolve) => pendingData.then(({ data: { value } }) => {
|
|
53
|
+
updateRefs(value.data, value.sourceMap);
|
|
54
|
+
resolve({ ...pendingData, data, sourceMap, encodeDataAttribute });
|
|
55
|
+
})), { ...pendingData, data, sourceMap, encodeDataAttribute });
|
|
56
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const useSanityLiveMode: () => () => void
|
|
1
|
+
export declare const useSanityLiveMode: () => Promise<() => void>;
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { onScopeDispose } from "vue";
|
|
2
1
|
import useSanityClient from "../utils/useSanityClient.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
export const useSanityLiveMode = async () => {
|
|
6
4
|
if (import.meta.client) {
|
|
7
|
-
const client = useSanityClient("default");
|
|
5
|
+
const client = await useSanityClient(true, "default", useRuntimeConfig().public.sanity);
|
|
8
6
|
if (client.queryStore) {
|
|
9
|
-
|
|
10
|
-
client: client.client
|
|
11
|
-
});
|
|
7
|
+
return client.queryStore.enableLiveMode({ client: client.client });
|
|
12
8
|
}
|
|
13
9
|
}
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
return () => {
|
|
11
|
+
};
|
|
16
12
|
};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
useCookie,
|
|
7
7
|
useRuntimeConfig
|
|
8
8
|
} from "#imports";
|
|
9
|
-
export default defineNuxtPlugin(() => {
|
|
9
|
+
export default defineNuxtPlugin(async () => {
|
|
10
10
|
const visualEditingState = useSanityVisualEditingState();
|
|
11
11
|
const $config = useRuntimeConfig();
|
|
12
12
|
const { visualEditing } = $config.public.sanity;
|
|
@@ -24,7 +24,7 @@ export default defineNuxtPlugin(() => {
|
|
|
24
24
|
refresh: visualEditing?.refresh,
|
|
25
25
|
zIndex: visualEditing?.zIndex
|
|
26
26
|
});
|
|
27
|
-
if (visualEditing?.mode === "live-visual-editing") useSanityLiveMode();
|
|
27
|
+
if (visualEditing?.mode === "live-visual-editing") await useSanityLiveMode();
|
|
28
28
|
break;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getRequestURL } from "h3";
|
|
2
2
|
import { hash } from "ohash";
|
|
3
|
+
import { useStorage } from "nitropack/runtime/internal/storage";
|
|
3
4
|
import resolveSanityImageUrl from "../../utils/resolveSanityImageUrl.js";
|
|
4
|
-
import { useStorage } from "#imports";
|
|
5
5
|
const TTL = 60 * 60 * 24 * 365;
|
|
6
6
|
export default defineEventHandler(async (event) => {
|
|
7
7
|
const queryParams = getRequestURL(event).searchParams;
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
setResponseHeader
|
|
6
6
|
} from "h3";
|
|
7
7
|
import { hash } from "ohash";
|
|
8
|
+
import { useStorage } from "nitropack/runtime/internal/storage";
|
|
8
9
|
import useSanityClient from "../../utils/useSanityClient.js";
|
|
9
|
-
import { useRuntimeConfig
|
|
10
|
+
import { useRuntimeConfig } from "#imports";
|
|
10
11
|
const TTL = 60 * 60 * 8;
|
|
11
12
|
export default defineEventHandler(async (event) => {
|
|
12
13
|
const url = getRequestURL(event);
|
|
@@ -38,7 +39,7 @@ export default defineEventHandler(async (event) => {
|
|
|
38
39
|
{ perspective }
|
|
39
40
|
);
|
|
40
41
|
if (!result)
|
|
41
|
-
throw createError({ statusCode:
|
|
42
|
+
throw createError({ statusCode: 404, statusMessage: "No results" });
|
|
42
43
|
setResponseHeader(event, "Content-Type", "application/json");
|
|
43
44
|
if (Object.keys(result).length === 0)
|
|
44
45
|
return {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHmac } from "node:crypto";
|
|
2
|
-
import { defineEventHandler, readRawBody, setResponseStatus
|
|
3
|
-
import {
|
|
2
|
+
import { defineEventHandler, getRequestHeader, readRawBody, setResponseStatus } from "h3";
|
|
3
|
+
import { useStorage } from "nitropack/runtime/internal/storage";
|
|
4
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const body = await readRawBody(event);
|
|
6
7
|
const signatureHeader = getRequestHeader(event, "sanity-webhook-signature");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModuleOptions } from '@devite/nuxt-sanity';
|
|
1
2
|
import type SanityClient from '../../client/SanityClient.js';
|
|
2
|
-
import type { SanityClientType } from '../../
|
|
3
|
-
export default function useSanityClient(type?: SanityClientType): SanityClient;
|
|
3
|
+
import type { SanityClientType } from '../../client/SanityClient.js';
|
|
4
|
+
export default function useSanityClient(type?: SanityClientType, config?: ModuleOptions): SanityClient;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import defu from "defu";
|
|
2
|
-
import
|
|
2
|
+
import DefaultSanityClient from "../../client/DefaultSanityClient.js";
|
|
3
|
+
import MinimalSanityClient from "../../client/MinimalSanityClient.js";
|
|
3
4
|
import { useRuntimeConfig } from "#imports";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const sanityConfig = defu(
|
|
5
|
+
const clients = {};
|
|
6
|
+
export default function useSanityClient(type, config) {
|
|
7
|
+
const sanityConfig = config || defu(useRuntimeConfig().sanity, useRuntimeConfig().public.sanity || {});
|
|
7
8
|
const visualEditingEnabled = type !== "minimal" && sanityConfig.visualEditing && sanityConfig.visualEditing.previewMode !== false;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
);
|
|
9
|
+
const clientType = (type || (sanityConfig.minimalClient ? "minimal" : "default")) + (visualEditingEnabled ? "-visual-editing" : "");
|
|
10
|
+
if (clientType in clients) return clients[clientType];
|
|
11
|
+
const clientConfig = visualEditingEnabled ? {
|
|
12
|
+
...sanityConfig,
|
|
13
|
+
token: sanityConfig.visualEditing?.token,
|
|
14
|
+
useCdn: false
|
|
15
|
+
} : sanityConfig;
|
|
16
|
+
const client = new (clientType === "minimal" ? MinimalSanityClient : DefaultSanityClient)(clientConfig);
|
|
17
|
+
if (visualEditingEnabled) client.createQueryStore();
|
|
18
|
+
clients[clientType] = client;
|
|
19
|
+
return client;
|
|
17
20
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
|
|
2
|
+
import type { Reactive } from 'vue';
|
|
3
|
+
import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
|
|
4
|
+
import type SanityClient from '../../client/SanityClient.js';
|
|
5
|
+
export declare function fetchSanityData<T>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, perspective: ClientPerspective, callback: (data: T | null, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void): Promise<void>;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { useSanityQuery } from "../composables/useSanityQuery.js";
|
|
2
1
|
import { IMAGE_ASSET_PROJECTION } from "./projections.js";
|
|
2
|
+
import { useSanityQuery } from "#imports";
|
|
3
3
|
export const resolveImageAssetById = async (id) => {
|
|
4
|
-
return useSanityQuery(
|
|
4
|
+
return (await useSanityQuery(
|
|
5
|
+
`*[_type == "sanity.imageAsset" && _id == $assetId][0] ${IMAGE_ASSET_PROJECTION}`,
|
|
6
|
+
{ assetId: id }
|
|
7
|
+
)).data;
|
|
5
8
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { useSanityQuery } from "
|
|
1
|
+
import { useSanityQuery } from "#imports";
|
|
2
2
|
export const resolveInternalLink = async (reference) => {
|
|
3
|
-
return
|
|
3
|
+
return (await useSanityQuery(
|
|
4
|
+
`*[_id == $documentId][0] { '_type': 'linkInternal', 'slug': coalesce(slug.current, '/') }`,
|
|
5
|
+
{ documentId: reference._ref }
|
|
6
|
+
)).data;
|
|
4
7
|
};
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
import type { ModuleOptions } from '@devite/nuxt-sanity';
|
|
1
2
|
import type SanityClient from '../client/SanityClient.js';
|
|
2
|
-
|
|
3
|
+
import type { SanityClientType } from '../client/SanityClient.js';
|
|
4
|
+
export default function useSanityClient(visualEditing: boolean, type: SanityClientType, config: ModuleOptions): Promise<SanityClient>;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
const clients = {};
|
|
2
|
+
export default async function useSanityClient(visualEditing, type, config) {
|
|
3
|
+
const clientType = visualEditing ? "default" : type;
|
|
4
|
+
if (clientType in clients) return clients[clientType];
|
|
5
|
+
const clientConfig = {
|
|
6
|
+
...config,
|
|
7
|
+
stega: visualEditing && config.stega
|
|
8
|
+
};
|
|
9
|
+
const client = new (await (clientType === "minimal" ? import("../client/MinimalSanityClient.ts") : import("../client/DefaultSanityClient.ts"))).default(clientConfig);
|
|
10
|
+
if (visualEditing) client.createQueryStore();
|
|
11
|
+
clients[clientType] = client;
|
|
12
|
+
return client;
|
|
8
13
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
|
|
2
|
+
import type { Reactive } from 'vue';
|
|
3
|
+
import { type EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
|
|
4
|
+
import type SanityClient from '../../client/SanityClient.js';
|
|
5
|
+
export declare function fetchSanityData<T>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, perspective: ClientPerspective, callback: (data: T | null, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void): Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
|
|
2
|
+
export async function fetchSanityData(query, params, client, perspective, callback) {
|
|
3
|
+
function updateResult(data2, sourceMap2) {
|
|
4
|
+
const encodeDataAttribute = sourceMap2 ? defineEncodeDataAttribute(data2, sourceMap2, client.config.visualEditing?.studioUrl) : void 0;
|
|
5
|
+
callback(data2, sourceMap2, encodeDataAttribute);
|
|
6
|
+
}
|
|
7
|
+
const defaultClient = client;
|
|
8
|
+
const proxyClient = {
|
|
9
|
+
fetch: (query2, params2, options) => $fetch(client.config.visualEditing.proxyEndpoint || "/_sanity/fetch", {
|
|
10
|
+
method: "POST",
|
|
11
|
+
body: { query: query2, params: params2, options }
|
|
12
|
+
})
|
|
13
|
+
};
|
|
14
|
+
const currentClient = import.meta.server ? defaultClient.queryStore.unstable__serverClient.instance || defaultClient.client : proxyClient;
|
|
15
|
+
const { result: data, resultSourceMap: sourceMap } = await currentClient.fetch(query, params || {}, {
|
|
16
|
+
perspective,
|
|
17
|
+
filterResponse: false,
|
|
18
|
+
resultSourceMap: "withKeyArraySelector"
|
|
19
|
+
});
|
|
20
|
+
updateResult(data, sourceMap);
|
|
21
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Reactive } from 'vue';
|
|
2
|
+
import type { ContentSourceMap, QueryParams } from '@sanity/client';
|
|
3
|
+
import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
|
|
4
|
+
import type SanityClient from '../../client/SanityClient.js';
|
|
5
|
+
export declare const subscribeToChanges: <T, E>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, updateData: (data: T, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void) => void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { toRaw } from "vue";
|
|
2
|
+
import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
|
|
3
|
+
export const subscribeToChanges = (query, params, client, updateData) => {
|
|
4
|
+
let unsubscribe = () => {
|
|
5
|
+
};
|
|
6
|
+
function setupFetcher(cb) {
|
|
7
|
+
unsubscribe();
|
|
8
|
+
const deepClonedParams = params ? JSON.parse(JSON.stringify(toRaw(params))) : void 0;
|
|
9
|
+
const fetcher = client.queryStore.createFetcherStore(query, deepClonedParams, void 0);
|
|
10
|
+
unsubscribe = fetcher.subscribe((newSnapshot) => {
|
|
11
|
+
if (newSnapshot.data) {
|
|
12
|
+
const encodeDataAttribute = newSnapshot.sourceMap ? defineEncodeDataAttribute(newSnapshot.data, newSnapshot.sourceMap, client.config.visualEditing?.studioUrl) : void 0;
|
|
13
|
+
updateData(newSnapshot.data, newSnapshot.sourceMap, encodeDataAttribute);
|
|
14
|
+
cb?.(newSnapshot);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
setupFetcher();
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devite/nuxt-sanity",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Advanced Sanity integration for Nuxt.js.",
|
|
5
5
|
"repository": "devite-io/nuxt-sanity",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"eslint": "^9.17.0",
|
|
46
46
|
"h3": "^1.13.0",
|
|
47
47
|
"nuxt": "^3.14.1592",
|
|
48
|
+
"react": "18.3.1",
|
|
48
49
|
"typescript": "~5.6.3",
|
|
49
50
|
"vitest": "^2.1.8",
|
|
50
51
|
"vitest-environment-nuxt": "1.0.1",
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { AsyncDataOptions } from 'nuxt/app';
|
|
2
|
-
import type { QueryParams } from '@sanity/client';
|
|
3
|
-
import { type AsyncSanityData, type SanityQueryResponse } from './useSanityQuery.js';
|
|
4
|
-
export declare const useLazySanityQuery: <T = unknown, E = Error>(query: string, _params?: QueryParams, options?: AsyncDataOptions<SanityQueryResponse<T | null>>) => AsyncSanityData<T | null, E>;
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { hash } from "ohash";
|
|
2
|
-
import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
|
|
3
|
-
import { onScopeDispose, reactive, ref } from "vue";
|
|
4
|
-
import useSanityClient from "../utils/useSanityClient.js";
|
|
5
|
-
import { useAsyncData, useLazyAsyncData } from "#imports";
|
|
6
|
-
export const useSanityQuery = (query, _params = {}, _options = {}, lazy = false) => {
|
|
7
|
-
const { client: clientType, perspective: _perspective, ...options } = _options;
|
|
8
|
-
const client = clientType ? useSanityClient(clientType) : useSanityClient();
|
|
9
|
-
const hasQueryStore = "queryStore" in client && client.queryStore !== null;
|
|
10
|
-
const perspective = _perspective || (hasQueryStore ? "previewDrafts" : "published");
|
|
11
|
-
const reactiveParams = _params ? reactive(_params) : void 0;
|
|
12
|
-
if (reactiveParams) {
|
|
13
|
-
options.watch ||= [];
|
|
14
|
-
options.watch.push(reactiveParams);
|
|
15
|
-
}
|
|
16
|
-
const key = "sanity-" + hash(query + (reactiveParams ? JSON.stringify(reactiveParams) : ""));
|
|
17
|
-
const data = ref(null);
|
|
18
|
-
const sourceMap = ref(null);
|
|
19
|
-
const encodeDataAttribute = ref(() => {
|
|
20
|
-
});
|
|
21
|
-
function updateResult(newData, newSourceMap) {
|
|
22
|
-
data.value = newData;
|
|
23
|
-
sourceMap.value = newSourceMap || null;
|
|
24
|
-
if (client.config.visualEditing) {
|
|
25
|
-
encodeDataAttribute.value = defineEncodeDataAttribute(newData, newSourceMap, client.config.visualEditing?.studioUrl);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
let fetchFunc = async () => {
|
|
29
|
-
return { data: await client.fetch(query, reactiveParams || {}, { perspective }) };
|
|
30
|
-
};
|
|
31
|
-
if (hasQueryStore) {
|
|
32
|
-
let setupFetcher = function(cb) {
|
|
33
|
-
unsubscribe();
|
|
34
|
-
const deepClonedParams = _params ? JSON.parse(JSON.stringify(_params)) : void 0;
|
|
35
|
-
const fetcher = defaultClient.queryStore.createFetcherStore(query, deepClonedParams, void 0);
|
|
36
|
-
unsubscribe = fetcher.subscribe((newSnapshot) => {
|
|
37
|
-
if (newSnapshot.data) {
|
|
38
|
-
updateResult(newSnapshot.data, newSnapshot.sourceMap);
|
|
39
|
-
cb?.(newSnapshot);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
const defaultClient = client;
|
|
44
|
-
let unsubscribe = () => {
|
|
45
|
-
};
|
|
46
|
-
const proxyClient = {
|
|
47
|
-
fetch: (query2, params, options2) => $fetch(defaultClient.config.visualEditing.proxyEndpoint || "/_sanity/fetch", {
|
|
48
|
-
method: "POST",
|
|
49
|
-
body: { query: query2, params, options: options2 }
|
|
50
|
-
})
|
|
51
|
-
};
|
|
52
|
-
fetchFunc = async () => {
|
|
53
|
-
const currentClient = import.meta.server ? defaultClient.queryStore.unstable__serverClient.instance || defaultClient.client : proxyClient;
|
|
54
|
-
const { result: fetchData, resultSourceMap: sourceMap2 } = await currentClient.fetch(query, reactiveParams || {}, {
|
|
55
|
-
perspective,
|
|
56
|
-
filterResponse: false,
|
|
57
|
-
resultSourceMap: "withKeyArraySelector"
|
|
58
|
-
});
|
|
59
|
-
return sourceMap2 ? { data: fetchData, sourceMap: sourceMap2 } : { data: fetchData };
|
|
60
|
-
};
|
|
61
|
-
if (import.meta.client) setupFetcher();
|
|
62
|
-
onScopeDispose(unsubscribe);
|
|
63
|
-
}
|
|
64
|
-
const pendingData = lazy ? useLazyAsyncData(key, fetchFunc, options) : useAsyncData(key, fetchFunc, options);
|
|
65
|
-
return Object.assign(new Promise((resolve) => pendingData.then(({ data: { value } }) => {
|
|
66
|
-
updateResult(value.data, value.sourceMap);
|
|
67
|
-
resolve({ ...pendingData, data, sourceMap, encodeDataAttribute });
|
|
68
|
-
})), { ...pendingData, data, sourceMap, encodeDataAttribute });
|
|
69
|
-
};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ModuleOptions } from '@devite/nuxt-sanity';
|
|
2
|
-
import type SanityClient from '../client/SanityClient.js';
|
|
3
|
-
export type SanityClientType = 'minimal' | 'default';
|
|
4
|
-
export default function getOrCreateSanityClient(visualEditing: boolean, config: ModuleOptions, type?: SanityClientType): SanityClient;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import MinimalSanityClient from "../client/MinimalSanityClient.js";
|
|
2
|
-
import DefaultSanityClient from "../client/DefaultSanityClient.js";
|
|
3
|
-
const clients = {};
|
|
4
|
-
export default function getOrCreateSanityClient(visualEditing, config, type) {
|
|
5
|
-
const clientType = visualEditing ? "default" : type || (config.minimalClient ? "minimal" : "default");
|
|
6
|
-
if (clientType in clients) return clients[clientType];
|
|
7
|
-
const clientConfig = {
|
|
8
|
-
...config,
|
|
9
|
-
stega: visualEditing && config.stega
|
|
10
|
-
};
|
|
11
|
-
const client = clientType === "minimal" ? new MinimalSanityClient(clientConfig) : new DefaultSanityClient(clientConfig);
|
|
12
|
-
if (visualEditing && import.meta.client) client.createQueryStore();
|
|
13
|
-
clients[clientType] = client;
|
|
14
|
-
return client;
|
|
15
|
-
}
|