Skip to content

Commit

Permalink
feat: add multiple sanity client capability
Browse files Browse the repository at this point in the history
closes #2
  • Loading branch information
danielroe committed Aug 21, 2020
1 parent e16e297 commit 0b04120
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 32 deletions.
45 changes: 40 additions & 5 deletions docs/content/en/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: Configuration
description: 'Access text, images, and other media with Nuxt and the Sanity headless CMS.'
category: Getting started
position: 3
version: 0.23
---

By default, `@nuxtjs/sanity` will look for a `sanity.json` file in your project root directory, and it will read your `projectId` and `dataset` from there.
Expand Down Expand Up @@ -52,19 +53,19 @@ You can provide a token or leave blank to be an anonymous user. (You can also se
### `withCredentials`

- Type: **boolean**
- Default: **false**
- Default: **`false`**

Include credentials in requests made to Sanity. Useful if you want to take advantage of an existing authorisation to the Sanity CMS.

### `useCdn`

- Type: **boolean**
- Default: **true** in production or **false** if a token has been passed in
- Default: **`true`** in production or **`false`** if a token has been passed in

### `minimal`

- Type: **boolean**
- Default: **false**
- Default: **`false`**

Use an ultra-minimal Sanity client for making requests (a fork of [picosanity](https://github.com/rexxars/picosanity) with SSR-specific changes). It only supports `fetch` requests, but will significantly decrease your bundle size.

Expand All @@ -73,13 +74,47 @@ Use an ultra-minimal Sanity client for making requests (a fork of [picosanity](h
### `imageHelper`

- Type: **boolean**
- Default: **true**
- Default: **`true`**

Add a global `<SanityImage>` component to assist with URL transformations. See [the docs](/helpers/images) for more information.

### `contentHelper`

- Type: **boolean**
- Default: **true**
- Default: **`true`**

Add a global `<SanityContent>` component to display portable text. See [the docs](/helpers/portable-text) for more information.

### `additionalClients`

- Type: **Object**
- Default: **`{}`**

You can create additional clients. Each client's name will be the key of the object provided, and the options provided will be merged with the options of the default client.

The options that can be provided are:

- `projectId`
- `dataset`
- `token`
- `withCredentials`
- `useCdn`

So, for example:

```js{}[nuxt.config.js]
{
// ...
sanity: {
additionalClients: {
another: {
projectId: 'anotherproject',
},
},
},
}
```

<alert>Because these clients will be accessible directly off the `$sanity` helper, take care not to name them `client`, `fetch` or `setToken`, or they will conflict with the default client properties.

</alert>
11 changes: 11 additions & 0 deletions docs/content/en/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: Usage
description: 'Access text, images, and other media with Nuxt and the Sanity headless CMS.'
category: Getting started
position: 4
version: 0.23
---

This module globally injects a `$sanity` helper, meaning that you can access it anywhere using `this.$sanity`. For plugins, asyncData, fetch, nuxtServerInit and middleware, you can access it from `context.$sanity`.
Expand Down Expand Up @@ -59,3 +60,13 @@ export default async ({ req, $sanity }) => {
$sanity.setToken(token)
}
```

### Additional clients

If you have [configured additional clients](/configuration#additionalclients) you can access them directly off `$sanity`, with all the same properties and methods as specified above. So, for example:

```js{}[plugins/fetch.js]
export default async ({ $sanity }) => {
$sanity.another.fetch('*[type == "article"][0]')
}
```
3 changes: 3 additions & 0 deletions example/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const config = {
sanity: {
projectId: process.env.NODE_ENV === 'development' ? 'j1o4tmjp' : undefined,
dataset: 'production',
additionalClients: {
another: {},
},
},
build: {
extend (config) {
Expand Down
2 changes: 1 addition & 1 deletion example/pages/movie/_slug.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default Vue.extend({
LocalSanityImage: SanityImage,
},
async fetch () {
const movieDetails = await this.$sanity.fetch<QueryResult>(query, {
const movieDetails = await this.$sanity.another.fetch<QueryResult>(query, {
slug: this.$route.params.slug,
})
this.details = movieDetails
Expand Down
36 changes: 19 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export interface SanityModuleOptions extends Partial<SanityConfiguration> {
* @default true
*/
contentHelper?: boolean
/**
* Configuration for any additional clients
*/
additionalClients?: Record<string, Partial<SanityConfiguration>>
}
const isProd = process.env.NODE_ENV === 'production'

Expand All @@ -35,6 +39,7 @@ const DEFAULTS: SanityModuleOptions = {
withCredentials: false,
}
const CONFIG_KEY = 'sanity'
const HELPER_KEY = '$sanity'

function validateConfig ({ projectId, dataset }: SanityModuleOptions) {
if (isNuxtBuild) return
Expand Down Expand Up @@ -124,6 +129,7 @@ const nuxtModule: Module<SanityModuleOptions> = function (moduleOptions) {
withCredentials: options.withCredentials,
token: options.token,
}),
additionalClients: JSON.stringify(options.additionalClients),
},
})

Expand All @@ -143,39 +149,35 @@ const nuxtModule: Module<SanityModuleOptions> = function (moduleOptions) {
}
;(nuxtModule as any).meta = { name: '@nuxtjs/sanity' }

interface Client {
client: SanityClient
fetch: ReturnType<typeof createClient>['fetch']
setToken: (token: string) => void
}

type SanityHelper = Record<string, Client> & Client

declare module '@nuxt/types' {
interface NuxtConfig {
sanity: SanityModuleOptions
[CONFIG_KEY]: SanityModuleOptions
} // Nuxt 2.14+
interface Configuration {
sanity: SanityModuleOptions
[CONFIG_KEY]: SanityModuleOptions
} // Nuxt 2.9 - 2.13
interface NuxtAppOptions {
$sanity: {
client: SanityClient
fetch: ReturnType<typeof createClient>['fetch']
setToken: (token: string) => void
}
[HELPER_KEY]: SanityHelper
}
}

declare module 'vue/types/vue' {
interface Vue {
$sanity: {
client: SanityClient
fetch: ReturnType<typeof createClient>['fetch']
setToken: (token: string) => void
}
[HELPER_KEY]: SanityHelper
}
}

declare module 'vuex/types/index' {
interface Store<S> {
$sanity: {
client: SanityClient
fetch: ReturnType<typeof createClient>['fetch']
setToken: (token: string) => void
}
[HELPER_KEY]: SanityHelper
}
}

Expand Down
27 changes: 19 additions & 8 deletions templates/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,30 @@ Vue.component('SanityContent', SanityContent)
<% } %>

const _options = JSON.parse('<%= options.sanityConfig %>')
const _additionalClients = JSON.parse('<%= options.additionalClients %>')

const createSanity = options => ({
client: createClient(options),
fetch(...args) {
return this.client.fetch(...args)
},
setToken(token) {
this.client = createClient({ ...options, token })
},
})

/**
* @type {import('@nuxt/types').Plugin}
*/
export default async ({ $config }, inject) => {
const options = defu($config.sanity || {}, _options)
const options = defu($config && $config.sanity || {}, _options)
const additionalClients = defu($config && $config.sanity && $config.sanity.additionalClients || {}, _additionalClients)

inject('sanity', {
client: createClient(options),
fetch(...args) {
return this.client.fetch(...args)
},
setToken(token) {
this.client = createClient({ ...options, token })
}
...createSanity(options),
...Object.entries(additionalClients).reduce((clients, [name, clientOptions]) => {
clients[name] = createSanity(defu(clientOptions, options))
return clients
}, {})
})
}
3 changes: 2 additions & 1 deletion test/e2e/module.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ describe('module with default options', () => {
src: expect.stringContaining('plugin.js'),
fileName: 'sanity/plugin.js',
options: {
client: true,
client: false,
additionalClients: JSON.stringify({ another: {} }),
components: {
contentHelper: true,
imageHelper: true,
Expand Down

0 comments on commit 0b04120

Please sign in to comment.