@devite/nuxt-sanity 1.5.3 → 2.0.1

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.
Files changed (53) hide show
  1. package/README.md +3 -3
  2. package/dist/module.d.mts +62 -14
  3. package/dist/module.d.ts +62 -14
  4. package/dist/module.json +3 -3
  5. package/dist/module.mjs +98 -4
  6. package/dist/runtime/client/DefaultSanityClient.d.ts +15 -0
  7. package/dist/runtime/client/DefaultSanityClient.js +44 -0
  8. package/dist/runtime/client/MinimalSanityClient.d.ts +15 -0
  9. package/dist/runtime/client/MinimalSanityClient.js +59 -0
  10. package/dist/runtime/client/SanityClient.d.ts +10 -0
  11. package/dist/runtime/client/SanityClient.js +7 -0
  12. package/dist/runtime/components/SanityComponent.vue +6 -4
  13. package/dist/runtime/components/SanityImageAsset.vue +9 -5
  14. package/dist/runtime/components/SanityLinkExternal.vue +2 -1
  15. package/dist/runtime/components/SanityLinkInternal.vue +5 -7
  16. package/dist/runtime/components/SanityPage.vue +23 -14
  17. package/dist/runtime/components/SanityRichText.vue +3 -3
  18. package/dist/runtime/composables/useLazySanityQuery.d.ts +4 -0
  19. package/dist/runtime/composables/useLazySanityQuery.js +4 -0
  20. package/dist/runtime/composables/useSanityLiveMode.d.ts +1 -0
  21. package/dist/runtime/composables/useSanityLiveMode.js +16 -0
  22. package/dist/runtime/composables/useSanityQuery.d.ts +30 -0
  23. package/dist/runtime/composables/useSanityQuery.js +69 -0
  24. package/dist/runtime/composables/useSanityVisualEditing.d.ts +8 -0
  25. package/dist/runtime/composables/useSanityVisualEditing.js +44 -0
  26. package/dist/runtime/composables/useSanityVisualEditingState.d.ts +4 -0
  27. package/dist/runtime/composables/useSanityVisualEditingState.js +12 -0
  28. package/dist/runtime/plugins/visual-editing.d.ts +2 -0
  29. package/dist/runtime/plugins/visual-editing.js +30 -0
  30. package/dist/runtime/server/routes/preview/disable.d.ts +2 -0
  31. package/dist/runtime/server/routes/preview/disable.js +6 -0
  32. package/dist/runtime/server/routes/preview/enable.d.ts +2 -0
  33. package/dist/runtime/server/routes/preview/enable.js +20 -0
  34. package/dist/runtime/server/routes/proxy.d.ts +2 -0
  35. package/dist/runtime/server/routes/proxy.js +19 -0
  36. package/dist/runtime/server/tsconfig.json +3 -0
  37. package/dist/runtime/server/utils/useSanityClient.d.ts +3 -0
  38. package/dist/runtime/server/utils/useSanityClient.js +17 -0
  39. package/dist/runtime/utils/getOrCreateSanityClient.d.ts +4 -0
  40. package/dist/runtime/utils/getOrCreateSanityClient.js +15 -0
  41. package/dist/runtime/utils/groq.d.ts +8 -0
  42. package/dist/runtime/utils/groq.js +6 -0
  43. package/dist/runtime/utils/projections.d.ts +4 -4
  44. package/dist/runtime/utils/projections.js +1 -1
  45. package/dist/runtime/utils/resolveImageAssetById.d.ts +2 -2
  46. package/dist/runtime/utils/resolveImageAssetById.js +2 -2
  47. package/dist/runtime/utils/resolveInternalLink.d.ts +2 -2
  48. package/dist/runtime/utils/resolveInternalLink.js +2 -2
  49. package/dist/runtime/utils/useSanityClient.d.ts +2 -0
  50. package/dist/runtime/utils/useSanityClient.js +8 -0
  51. package/dist/types.d.mts +1 -7
  52. package/dist/types.d.ts +1 -7
  53. package/package.json +30 -15
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version][npm-version-src]][npm-version-href]
4
4
 
5
- Provides additional helper components and utilities for the [Nuxt Sanity Module][nuxt-sanity].
5
+ Advanced [Sanity](https://www.sanity.io/) integration for Nuxt.js. Based on the official [@nuxtjs/sanity][nuxt-sanity] module.
6
6
 
7
7
  ## Quick Setup
8
8
 
@@ -12,7 +12,7 @@ Install the module to your Nuxt application with one command:
12
12
  npx nuxi module add @devite/nuxt-sanity
13
13
  ```
14
14
 
15
- That's it! You can now use data from Sanity in your Nuxt app ✨
15
+ That's it! You can now use Sanity with your Nuxt app ✨
16
16
 
17
17
 
18
18
  ## Contribution
@@ -22,7 +22,7 @@ That's it! You can now use data from Sanity in your Nuxt app ✨
22
22
 
23
23
  ```bash
24
24
  # Install dependencies
25
- pnpm install && cd playground/cms && pnpm install && cd -
25
+ pnpm install
26
26
 
27
27
  # Generate type stubs
28
28
  pnpm dev:prepare
package/dist/module.d.mts CHANGED
@@ -1,27 +1,56 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { Image, Slug, PortableTextBlock } from '@sanity/types';
2
+ import { VisualEditingOptions as VisualEditingOptions$1, HistoryRefresh } from '@sanity/visual-editing';
3
+ import { ClientConfig } from '@sanity/client';
4
+ import { Slug, ImageAsset, PortableTextBlock } from '@sanity/types';
3
5
 
4
- interface SEO {
5
- _type: 'seo';
6
- indexable: boolean;
7
- title: string;
8
- shortTitle: string;
9
- description: string;
10
- image?: Image;
6
+ type ModuleOptions = ClientConfig & {
7
+ projectId: string;
8
+ /** @default 'production' */
9
+ dataset: string;
10
+ /** @default false */
11
+ minimalClient?: boolean;
12
+ /** @default true */
13
+ useCdn?: boolean;
14
+ /** @default '2024-08-08' */
15
+ apiVersion?: string;
16
+ visualEditing?: VisualEditingOptions;
17
+ };
18
+ interface VisualEditingOptions {
19
+ /** @default { enable: "/_sanity/preview/enable", disable: "/_sanity/preview/disable" } */
20
+ previewMode?: boolean | {
21
+ enable?: string;
22
+ disable?: string;
23
+ };
24
+ previewModeId?: string;
25
+ /** @default 'live-visual-editing' */
26
+ mode?: 'live-visual-editing' | 'visual-editing' | 'custom';
27
+ /** @default '/_sanity/fetch' */
28
+ proxyEndpoint?: string;
29
+ token?: string;
30
+ studioUrl?: string;
31
+ /** @default true */
32
+ stega?: boolean;
33
+ /** This function is only required if `mode` is set to 'visual-editing' */
34
+ refresh?: SanityVisualEditingRefreshHandler;
35
+ /** @default 100 */
36
+ zIndex?: VisualEditingOptions$1['zIndex'];
11
37
  }
38
+ type SanityVisualEditingRefreshHandler = (payload: HistoryRefresh, refreshDefault: () => false | Promise<void>) => false | Promise<void>;
12
39
 
13
40
  interface Page {
14
41
  _id: string;
15
42
  _type: 'page';
16
43
  title: string;
17
44
  slug: Slug;
18
- modules: Array<object>;
45
+ modules: SanityArray<SanityModule>;
19
46
  seo: SEO;
20
47
  }
21
48
 
22
49
  interface GlobalSEO {
23
50
  siteName: string;
24
- image: Image;
51
+ image: {
52
+ asset: ImageAsset;
53
+ };
25
54
  }
26
55
 
27
56
  interface LinkExternal {
@@ -35,20 +64,39 @@ interface LinkInternal {
35
64
  slug: string;
36
65
  }
37
66
 
67
+ interface SEO {
68
+ _type: 'seo';
69
+ indexable: boolean;
70
+ title: string;
71
+ shortTitle: string;
72
+ description: string;
73
+ image?: {
74
+ asset: ImageAsset;
75
+ };
76
+ }
77
+
38
78
  type RichText = PortableTextBlock[];
39
79
 
40
80
  interface Home {
41
81
  _type: 'home';
42
- modules: Array<object>;
82
+ modules: SanityArray<SanityModule>;
43
83
  seo: SEO;
44
84
  }
45
85
 
46
86
  interface NotFound {
47
87
  _type: 'notFound';
48
- modules: Array<object>;
88
+ modules: SanityArray<SanityModule>;
49
89
  seo: SEO;
50
90
  }
51
91
 
52
- declare const _default: _nuxt_schema.NuxtModule<_nuxt_schema.ModuleOptions, _nuxt_schema.ModuleOptions, false>;
92
+ type SanityModule = {
93
+ _type?: string;
94
+ };
95
+
96
+ type SanityArray<T> = Array<T & {
97
+ _key: string;
98
+ }>;
99
+
100
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
53
101
 
54
- export { type GlobalSEO, type Home, type LinkExternal, type LinkInternal, type NotFound, type Page, type RichText, type SEO, _default as default };
102
+ export { type GlobalSEO, type Home, type LinkExternal, type LinkInternal, type ModuleOptions, type NotFound, type Page, type RichText, type SEO, type SanityArray, type SanityModule, type SanityVisualEditingRefreshHandler, type VisualEditingOptions, _default as default };
package/dist/module.d.ts CHANGED
@@ -1,27 +1,56 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { Image, Slug, PortableTextBlock } from '@sanity/types';
2
+ import { VisualEditingOptions as VisualEditingOptions$1, HistoryRefresh } from '@sanity/visual-editing';
3
+ import { ClientConfig } from '@sanity/client';
4
+ import { Slug, ImageAsset, PortableTextBlock } from '@sanity/types';
3
5
 
4
- interface SEO {
5
- _type: 'seo';
6
- indexable: boolean;
7
- title: string;
8
- shortTitle: string;
9
- description: string;
10
- image?: Image;
6
+ type ModuleOptions = ClientConfig & {
7
+ projectId: string;
8
+ /** @default 'production' */
9
+ dataset: string;
10
+ /** @default false */
11
+ minimalClient?: boolean;
12
+ /** @default true */
13
+ useCdn?: boolean;
14
+ /** @default '2024-08-08' */
15
+ apiVersion?: string;
16
+ visualEditing?: VisualEditingOptions;
17
+ };
18
+ interface VisualEditingOptions {
19
+ /** @default { enable: "/_sanity/preview/enable", disable: "/_sanity/preview/disable" } */
20
+ previewMode?: boolean | {
21
+ enable?: string;
22
+ disable?: string;
23
+ };
24
+ previewModeId?: string;
25
+ /** @default 'live-visual-editing' */
26
+ mode?: 'live-visual-editing' | 'visual-editing' | 'custom';
27
+ /** @default '/_sanity/fetch' */
28
+ proxyEndpoint?: string;
29
+ token?: string;
30
+ studioUrl?: string;
31
+ /** @default true */
32
+ stega?: boolean;
33
+ /** This function is only required if `mode` is set to 'visual-editing' */
34
+ refresh?: SanityVisualEditingRefreshHandler;
35
+ /** @default 100 */
36
+ zIndex?: VisualEditingOptions$1['zIndex'];
11
37
  }
38
+ type SanityVisualEditingRefreshHandler = (payload: HistoryRefresh, refreshDefault: () => false | Promise<void>) => false | Promise<void>;
12
39
 
13
40
  interface Page {
14
41
  _id: string;
15
42
  _type: 'page';
16
43
  title: string;
17
44
  slug: Slug;
18
- modules: Array<object>;
45
+ modules: SanityArray<SanityModule>;
19
46
  seo: SEO;
20
47
  }
21
48
 
22
49
  interface GlobalSEO {
23
50
  siteName: string;
24
- image: Image;
51
+ image: {
52
+ asset: ImageAsset;
53
+ };
25
54
  }
26
55
 
27
56
  interface LinkExternal {
@@ -35,20 +64,39 @@ interface LinkInternal {
35
64
  slug: string;
36
65
  }
37
66
 
67
+ interface SEO {
68
+ _type: 'seo';
69
+ indexable: boolean;
70
+ title: string;
71
+ shortTitle: string;
72
+ description: string;
73
+ image?: {
74
+ asset: ImageAsset;
75
+ };
76
+ }
77
+
38
78
  type RichText = PortableTextBlock[];
39
79
 
40
80
  interface Home {
41
81
  _type: 'home';
42
- modules: Array<object>;
82
+ modules: SanityArray<SanityModule>;
43
83
  seo: SEO;
44
84
  }
45
85
 
46
86
  interface NotFound {
47
87
  _type: 'notFound';
48
- modules: Array<object>;
88
+ modules: SanityArray<SanityModule>;
49
89
  seo: SEO;
50
90
  }
51
91
 
52
- declare const _default: _nuxt_schema.NuxtModule<_nuxt_schema.ModuleOptions, _nuxt_schema.ModuleOptions, false>;
92
+ type SanityModule = {
93
+ _type?: string;
94
+ };
95
+
96
+ type SanityArray<T> = Array<T & {
97
+ _key: string;
98
+ }>;
99
+
100
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
53
101
 
54
- export { type GlobalSEO, type Home, type LinkExternal, type LinkInternal, type NotFound, type Page, type RichText, type SEO, _default as default };
102
+ export { type GlobalSEO, type Home, type LinkExternal, type LinkInternal, type ModuleOptions, type NotFound, type Page, type RichText, type SEO, type SanityArray, type SanityModule, type SanityVisualEditingRefreshHandler, type VisualEditingOptions, _default as default };
package/dist/module.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@devite/nuxt-sanity",
3
- "configKey": "@devite/nuxt-sanity",
4
- "version": "1.5.3",
3
+ "version": "2.0.1",
4
+ "configKey": "sanity",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
- "unbuild": "unknown"
7
+ "unbuild": "2.0.0"
8
8
  }
9
9
  }
package/dist/module.mjs CHANGED
@@ -1,14 +1,108 @@
1
- import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
1
+ import crypto from 'node:crypto';
2
+ import { defineNuxtModule, createResolver, addPlugin, addServerHandler, addImportsDir, addComponentsDir } from '@nuxt/kit';
3
+ import defu from 'defu';
4
+
5
+ const name = "@devite/nuxt-sanity";
6
+ const version = "2.0.1";
2
7
 
3
8
  const module = defineNuxtModule({
4
9
  meta: {
5
- name: "@devite/nuxt-sanity"
10
+ name,
11
+ version,
12
+ configKey: "sanity"
6
13
  },
7
- async setup(_options, _nuxt) {
14
+ defaults: {},
15
+ async setup(options, nuxt) {
8
16
  const { resolve } = createResolver(import.meta.url);
17
+ const moduleConfig = defu(nuxt.options.runtimeConfig.public.sanity, {
18
+ projectId: options.projectId,
19
+ dataset: options.dataset || "production",
20
+ minimalClient: options.minimalClient || false,
21
+ useCdn: options.useCdn || true,
22
+ apiVersion: options.apiVersion || "2024-08-08",
23
+ visualEditing: options.visualEditing || null
24
+ });
25
+ if (options.visualEditing) {
26
+ const previewMode = moduleConfig.visualEditing.previewMode !== false;
27
+ const visualEditingConfig = defu(moduleConfig.visualEditing, {
28
+ mode: "live-visual-editing",
29
+ previewMode: previewMode ? defu(moduleConfig.visualEditing.previewMode, {
30
+ enable: "/_sanity/preview/enable",
31
+ disable: "/_sanity/preview/disable"
32
+ }) : false,
33
+ previewModeId: previewMode ? crypto.randomBytes(16).toString("hex") : "",
34
+ proxyEndpoint: "/_sanity/fetch",
35
+ stega: true,
36
+ zIndex: 100,
37
+ token: ""
38
+ });
39
+ if (!moduleConfig.visualEditing.token?.length)
40
+ console.warn('Visual editing requires a token with "read" access');
41
+ if (!visualEditingConfig.studioUrl)
42
+ console.warn("Visual editing requires a studio URL");
43
+ if (visualEditingConfig.mode === "live-visual-editing" && !visualEditingConfig.stega)
44
+ console.warn('Visual Editing requires "stega" to be enabled in "live-visual-editing" mode');
45
+ nuxt.options.build.transpile.push(
46
+ "async-cache-dedupe",
47
+ "@sanity/core-loader",
48
+ "@sanity/preview-url-secret"
49
+ );
50
+ nuxt.options.vite.resolve = defu(nuxt.options.vite.resolve, {
51
+ dedupe: ["@sanity/client"]
52
+ });
53
+ nuxt.options.vite.optimizeDeps = defu(nuxt.options.vite.optimizeDeps, {
54
+ include: [
55
+ `${name} > @sanity/visual-editing > @sanity/mutate > lodash/groupBy.js`,
56
+ `${name} > @sanity/visual-editing > react`,
57
+ `${name} > @sanity/visual-editing > react/jsx-runtime`,
58
+ `${name} > @sanity/visual-editing > react-dom`,
59
+ `${name} > @sanity/visual-editing > react-dom/client`,
60
+ `${name} > @sanity/visual-editing > react-compiler-runtime`,
61
+ "@sanity/client"
62
+ ]
63
+ });
64
+ addPlugin({ src: resolve("runtime/plugins/visual-editing") });
65
+ if (previewMode) {
66
+ addServerHandler({
67
+ method: "get",
68
+ route: visualEditingConfig.previewMode.enable,
69
+ handler: resolve("runtime/server/routes/preview/enable")
70
+ });
71
+ addServerHandler({
72
+ method: "get",
73
+ route: visualEditingConfig.previewMode.disable,
74
+ handler: resolve("runtime/server/routes/preview/disable")
75
+ });
76
+ }
77
+ addServerHandler({
78
+ method: "post",
79
+ route: visualEditingConfig.proxyEndpoint,
80
+ handler: resolve("runtime/server/routes/proxy")
81
+ });
82
+ moduleConfig.visualEditing = visualEditingConfig;
83
+ }
84
+ nuxt.options.runtimeConfig.sanity = moduleConfig;
85
+ nuxt.options.runtimeConfig.public.sanity = defu(nuxt.options.runtimeConfig.public.sanity, {
86
+ projectId: moduleConfig.projectId,
87
+ dataset: moduleConfig.dataset,
88
+ minimalClient: moduleConfig.minimalClient,
89
+ useCdn: moduleConfig.useCdn,
90
+ apiVersion: moduleConfig.apiVersion,
91
+ perspective: "raw",
92
+ /* Visual Editing */
93
+ token: options.token || "",
94
+ withCredentials: options.withCredentials || false,
95
+ stega: moduleConfig.visualEditing && moduleConfig.visualEditing.stega !== false && moduleConfig.visualEditing.previewMode !== false && { enabled: true, studioUrl: moduleConfig.visualEditing.studioUrl } || {},
96
+ visualEditing: moduleConfig.visualEditing
97
+ });
98
+ addImportsDir(resolve("runtime/client"));
99
+ addImportsDir(resolve("runtime/composables"));
100
+ addImportsDir(resolve("runtime/utils/groq"));
101
+ addImportsDir(resolve("runtime/utils/projections"));
102
+ addImportsDir(resolve("runtime/utils/resolveImageAssetById"));
103
+ addImportsDir(resolve("runtime/utils/resolveInternalLink"));
9
104
  await addComponentsDir({ path: resolve("runtime/components") });
10
105
  await addComponentsDir({ path: "~/sanity", global: true, prefix: "Sanity" });
11
- addImportsDir(resolve("runtime/utils"));
12
106
  }
13
107
  });
14
108
 
@@ -0,0 +1,15 @@
1
+ import { type ClientPerspective, type QueryParams, type SanityClient as SanityClientType } from '@sanity/client';
2
+ import type { ModuleOptions } from '@devite/nuxt-sanity';
3
+ import { type QueryStore } from '@sanity/core-loader';
4
+ import SanityClient from './SanityClient.js';
5
+ declare class DefaultSanityClient extends SanityClient {
6
+ readonly client: SanityClientType;
7
+ queryStore: QueryStore | null;
8
+ constructor(config: ModuleOptions);
9
+ fetch<T = unknown>(query: string, params: QueryParams, options?: {
10
+ perspective?: ClientPerspective;
11
+ }): Promise<T>;
12
+ createQueryStore(tag?: string): void;
13
+ clone(): DefaultSanityClient;
14
+ }
15
+ export default DefaultSanityClient;
@@ -0,0 +1,44 @@
1
+ import {
2
+ createClient
3
+ } from "@sanity/client";
4
+ import { createQueryStore as createCoreQueryStore } from "@sanity/core-loader";
5
+ import SanityClient from "./SanityClient.js";
6
+ class DefaultSanityClient extends SanityClient {
7
+ client;
8
+ queryStore = null;
9
+ constructor(config) {
10
+ super(config);
11
+ this.client = createClient(config);
12
+ }
13
+ async fetch(query, params, options) {
14
+ return await this.client.fetch(query, params, options);
15
+ }
16
+ createQueryStore(tag) {
17
+ const queryStore = createCoreQueryStore({
18
+ tag: tag || "nuxt-loader",
19
+ client: false,
20
+ ssr: true
21
+ });
22
+ if (import.meta.server) {
23
+ const serverClient = this.client.withConfig({
24
+ perspective: "previewDrafts",
25
+ token: this.config.token,
26
+ useCdn: false
27
+ });
28
+ queryStore.setServerClient(serverClient);
29
+ }
30
+ this.queryStore = queryStore;
31
+ }
32
+ clone() {
33
+ return new DefaultSanityClient({
34
+ useCdn: this.config.useCdn,
35
+ projectId: this.config.projectId,
36
+ dataset: this.config.dataset,
37
+ apiVersion: this.config.apiVersion,
38
+ withCredentials: this.config.withCredentials,
39
+ token: this.config.token,
40
+ perspective: this.config.perspective
41
+ });
42
+ }
43
+ }
44
+ export default DefaultSanityClient;
@@ -0,0 +1,15 @@
1
+ import type { ClientPerspective, QueryParams } from '@sanity/client';
2
+ import type { ModuleOptions } from '@devite/nuxt-sanity';
3
+ import SanityClient from './SanityClient.js';
4
+ declare class MinimalSanityClient extends SanityClient {
5
+ private readonly queryPath;
6
+ private readonly fetchOptions;
7
+ constructor(config: ModuleOptions);
8
+ private getByteLength;
9
+ private toQueryString;
10
+ fetch<T>(query: string, params: QueryParams, _options?: {
11
+ perspective?: ClientPerspective;
12
+ }): Promise<T>;
13
+ clone(): MinimalSanityClient;
14
+ }
15
+ export default MinimalSanityClient;
@@ -0,0 +1,59 @@
1
+ import { $fetch } from "ofetch";
2
+ import SanityClient from "./SanityClient.js";
3
+ const API_HOST = "api.sanity.io";
4
+ const API_CDN_HOST = "apicdn.sanity.io";
5
+ class MinimalSanityClient extends SanityClient {
6
+ queryPath;
7
+ fetchOptions;
8
+ constructor(config) {
9
+ super({
10
+ ...config,
11
+ perspective: config.perspective || "raw",
12
+ useCdn: config.perspective === "previewDrafts" ? false : config.useCdn
13
+ });
14
+ this.queryPath = `/v${config.apiVersion}/data/query/${config.dataset}`;
15
+ this.fetchOptions = {
16
+ headers: {
17
+ ...config.token ? { Authorization: `Bearer ${config.token}` } : {},
18
+ Accept: "application/json",
19
+ ...import.meta.server ? { "accept-encoding": "gzip, deflate" } : {}
20
+ }
21
+ };
22
+ if (import.meta.client) {
23
+ this.fetchOptions.credentials = config.withCredentials ? "include" : "omit";
24
+ }
25
+ }
26
+ getByteLength(query) {
27
+ return encodeURI(query).split(/%..|./).length;
28
+ }
29
+ toQueryString(query, params) {
30
+ const baseQueryStr = `?query=${encodeURIComponent(query)}`;
31
+ return Object.keys(params).reduce((acc, paramName) => {
32
+ return acc + `&${encodeURIComponent(`$${paramName}`)}=${encodeURIComponent(JSON.stringify(params[paramName]))}`;
33
+ }, baseQueryStr);
34
+ }
35
+ async fetch(query, params, _options) {
36
+ const perspectiveQueryString = `&perspective=${_options?.perspective || this.config.perspective}`;
37
+ const queryString = this.toQueryString(query, params || {}) + perspectiveQueryString;
38
+ const byteLength = this.getByteLength(queryString);
39
+ const isEligibleForGetRequest = byteLength <= 9e3;
40
+ const queryHost = this.config.useCdn && isEligibleForGetRequest ? API_CDN_HOST : API_HOST;
41
+ return (await $fetch(`https://${this.config.projectId}.${queryHost + this.queryPath}${queryString}`, {
42
+ ...this.fetchOptions,
43
+ method: isEligibleForGetRequest ? "GET" : "POST",
44
+ body: !isEligibleForGetRequest ? { query, params } : void 0
45
+ })).result;
46
+ }
47
+ clone() {
48
+ return new MinimalSanityClient({
49
+ useCdn: this.config.useCdn,
50
+ projectId: this.config.projectId,
51
+ dataset: this.config.dataset,
52
+ apiVersion: this.config.apiVersion,
53
+ withCredentials: this.config.withCredentials,
54
+ token: this.config.token,
55
+ perspective: this.config.perspective
56
+ });
57
+ }
58
+ }
59
+ export default MinimalSanityClient;
@@ -0,0 +1,10 @@
1
+ import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
2
+ import type { ModuleOptions } from '@devite/nuxt-sanity';
3
+ export default abstract class SanityClient {
4
+ config: ModuleOptions;
5
+ sourceMap: ContentSourceMap | undefined;
6
+ protected constructor(config: ModuleOptions);
7
+ abstract fetch<T = unknown>(query: string, params: QueryParams, options?: {
8
+ perspective?: ClientPerspective;
9
+ }): Promise<T>;
10
+ }
@@ -0,0 +1,7 @@
1
+ export default class SanityClient {
2
+ config;
3
+ sourceMap = void 0;
4
+ constructor(config) {
5
+ this.config = config;
6
+ }
7
+ }
@@ -18,11 +18,11 @@
18
18
  </template>
19
19
 
20
20
  <script setup lang="ts">
21
- import type { Component } from '@nuxt/schema'
22
- import { computed, ref, resolveComponent } from '#imports'
23
- import { SanityLinkExternal, SanityLinkInternal, SanityRichText } from '#components'
21
+ import { type Component, computed, ref, resolveComponent } from 'vue'
22
+ import type { SanityModule } from '@devite/nuxt-sanity'
23
+ import { SanityImageAsset, SanityLinkExternal, SanityLinkInternal, SanityRichText } from '#components'
24
24
 
25
- const { data } = defineProps<{ data?: { _type?: string } | Array<{ _type: string }> }>()
25
+ const { data } = defineProps<{ data?: SanityModule | Array<SanityModule> }>()
26
26
 
27
27
  const component = computed<Component | null>(() => {
28
28
  if (Array.isArray(data) && data.every((item) => item._type === 'block')) {
@@ -37,6 +37,8 @@ const component = computed<Component | null>(() => {
37
37
  return SanityLinkInternal
38
38
  case 'linkExternal':
39
39
  return SanityLinkExternal
40
+ case 'sanity.imageAsset':
41
+ return SanityImageAsset
40
42
  default: {
41
43
  const upperCamelCase = type.charAt(0).toUpperCase() + type.slice(1)
42
44
  const resolvedComponent = resolveComponent('Sanity' + upperCamelCase)
@@ -6,7 +6,7 @@
6
6
  :width="imageAsset.metadata.dimensions.width"
7
7
  :height="imageAsset.metadata.dimensions.height"
8
8
  :alt="imageAsset.altText"
9
- :placeholder="imageAsset.metadata.lqip"
9
+ :placeholder="loading === 'eager' ? undefined : imageAsset.metadata.lqip"
10
10
  :loading="loading"
11
11
  :format="imageAsset.mimeType === 'image/svg+xml' ? undefined : 'webp'"
12
12
  draggable="false"
@@ -15,10 +15,14 @@
15
15
 
16
16
  <script setup lang="ts">
17
17
  import type { ImageAsset, Reference } from '@sanity/types'
18
- import { type Ref, resolveImageAssetById } from '#imports'
18
+ import type { Ref } from 'vue'
19
+ import { resolveImageAssetById } from '../utils/resolveImageAssetById'
19
20
 
20
- const { asset, loading = 'lazy' } = defineProps<{ asset?: ImageAsset | Reference, loading?: 'lazy' | 'eager' }>()
21
- const imageAsset: Ref<ImageAsset | undefined> | ImageAsset | undefined = asset?._ref
21
+ const { asset, loading = 'lazy' } = defineProps<{
22
+ asset?: ImageAsset | Reference
23
+ loading?: 'eager' | 'lazy'
24
+ }>()
25
+ const imageAsset: Ref<ImageAsset | null> | ImageAsset | undefined = asset?._ref
22
26
  ? await resolveImageAssetById((asset as Reference)._ref)
23
- : asset as (ImageAsset | undefined)
27
+ : (asset as ImageAsset | undefined)
24
28
  </script>
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <NuxtLink
3
3
  :to="data.url"
4
- :options="{ external: true, target: data.newWindow ? '_blank' : null }"
4
+ :target="data.newWindow ? '_blank' : '_self'"
5
+ external
5
6
  >
6
7
  <slot />
7
8
  </NuxtLink>
@@ -1,19 +1,17 @@
1
1
  <template>
2
- <NuxtLink
3
- v-if="resolvedLink"
4
- :to="resolvedLink.slug"
5
- >
2
+ <NuxtLink :to="resolvedLink?.slug">
6
3
  <slot />
7
4
  </NuxtLink>
8
5
  </template>
9
6
 
10
7
  <script setup lang="ts">
11
- import type { LinkInternal } from '@devite/nuxt-sanity'
12
8
  import type { Reference } from '@sanity/types'
13
- import { type Ref, resolveInternalLink } from '#imports'
9
+ import type { LinkInternal } from '@devite/nuxt-sanity'
10
+ import type { Ref } from 'vue'
11
+ import { resolveInternalLink } from '../utils/resolveInternalLink'
14
12
 
15
13
  const { data } = defineProps<{ data: LinkInternal | { reference: Reference } }>()
16
- const resolvedLink: Ref<LinkInternal | undefined> | LinkInternal = 'reference' in data
14
+ const resolvedLink: Ref<LinkInternal | null> | LinkInternal = 'reference' in data
17
15
  ? await resolveInternalLink(data.reference)
18
16
  : data as LinkInternal
19
17
  </script>