Skip to content

Commit

Permalink
feat: allow endpoint to be optional, fixes #199
Browse files Browse the repository at this point in the history
  • Loading branch information
lihbr committed Oct 24, 2023
1 parent 91c95c8 commit 0eb67c1
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 33 deletions.
3 changes: 3 additions & 0 deletions playground/app/prismic/disabled.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as prismic from '@prismicio/client'

export default prismic.createClient('200629-sms-hoy')
62 changes: 34 additions & 28 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default defineNuxtModule<PrismicModuleOptions>({
},
defaults: nuxt => ({
endpoint: '',
environment: '',
clientConfig: {},
client: '~/app/prismic/client',
linkResolver: '~/app/prismic/linkResolver',
Expand All @@ -56,44 +57,49 @@ export default defineNuxtModule<PrismicModuleOptions>({
const moduleOptions: PrismicModuleOptions = defu(nuxt.options.runtimeConfig.public.prismic, options)
nuxt.options.runtimeConfig.public.prismic = moduleOptions

if (!moduleOptions.endpoint) {
logger.warn('Options `endpoint` is required, disabling module...')
return
}

// Runtime dir boilerplate
const resolver = createResolver(import.meta.url)
nuxt.options.build.transpile.push(resolver.resolve('runtime'), '@nuxtjs/prismic', '@prismicio/vue')
nuxt.options.vite.optimizeDeps ||= {}
nuxt.options.vite.optimizeDeps.exclude ||= []
nuxt.options.vite.optimizeDeps.exclude.push('@prismicio/vue')

// Add runtime user code
const proxyUserFileWithUndefinedFallback = (filename: string, path: string, extensions = ['js', 'mjs', 'ts']) => {
const resolvedFilename = `prismic/proxy/${filename}.ts`
const resolvedPath = path.replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir)
const maybeUserFile = fileExists(resolvedPath, extensions)
const proxyUserFileWithUndefinedFallback =
(filename: string, path: string, extensions = ['js', 'mjs', 'ts']): boolean => {
const resolvedFilename = `prismic/proxy/${filename}.ts`
const resolvedPath = path.replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir)
const maybeUserFile = fileExists(resolvedPath, extensions)

if (maybeUserFile) {
if (maybeUserFile) {
// If user file exists, proxy it with vfs
logger.info(`Using user-defined \`${filename}\` at \`${maybeUserFile.replace(nuxt.options.srcDir, '~').replace(nuxt.options.rootDir, '~~').replace(/\\/g, '/')}\``)
logger.info(`Using user-defined \`${filename}\` at \`${maybeUserFile.replace(nuxt.options.srcDir, '~').replace(nuxt.options.rootDir, '~~').replace(/\\/g, '/')}\``)

addTemplate({
filename: resolvedFilename,
getContents: () => `export { default } from '${path}'`
})
} else {
addTemplate({
filename: resolvedFilename,
getContents: () => `export { default } from '${path}'`
})

return true
} else {
// Else provide `undefined` fallback
addTemplate({
filename: resolvedFilename,
getContents: () => 'export default undefined'
})
addTemplate({
filename: resolvedFilename,
getContents: () => 'export default undefined'
})

return false
}
}

const proxiedUserClient = proxyUserFileWithUndefinedFallback('client', moduleOptions.client!)
if (!moduleOptions.endpoint && !proxiedUserClient && !process.env.NUXT_PUBLIC_PRISMIC_ENDPOINT) {
logger.warn(`\`endpoint\` option is missing and \`${moduleOptions.client}\` was not found. At least one of them is required for the module to run. Disabling module...`)
return
}
proxyUserFileWithUndefinedFallback('client', moduleOptions.client!)
proxyUserFileWithUndefinedFallback('linkResolver', moduleOptions.linkResolver!)
proxyUserFileWithUndefinedFallback('richTextSerializer', moduleOptions.richTextSerializer!)

// Runtime dir boilerplate
const resolver = createResolver(import.meta.url)
nuxt.options.build.transpile.push(resolver.resolve('runtime'), '@nuxtjs/prismic', '@prismicio/vue')
nuxt.options.vite.optimizeDeps ||= {}
nuxt.options.vite.optimizeDeps.exclude ||= []
nuxt.options.vite.optimizeDeps.exclude.push('@prismicio/vue')

// Add plugin
addPlugin(resolver.resolve('runtime/plugin'))
addPlugin(resolver.resolve('runtime/plugin.client'))
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isRepositoryEndpoint, getRepositoryName } from '@prismicio/client'
import { isRepositoryEndpoint, getRepositoryName, type Client } from '@prismicio/client'
import { createPrismic } from '@prismicio/vue'

import type { PrismicModuleOptions } from '../types'
Expand All @@ -14,7 +14,7 @@ import richTextSerializer from '#build/prismic/proxy/richTextSerializer'

export default defineNuxtPlugin((nuxtApp) => {
const options: PrismicModuleOptions = useRuntimeConfig().public.prismic
const endpoint = options.environment || options.endpoint
const endpoint = options.environment || options.endpoint || (client as Client | undefined)?.endpoint || ''

const prismicPlugin = createPrismic({
...options,
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type PrismicModuleOptions = Omit<PrismicPluginOptions, 'endpoint' | 'clie
*
* @see Prismic client documentation {@link https://prismic.io/docs/technical-reference/prismicio-client}
*/
endpoint: string;
endpoint?: string;

/**
* The Prismic environment in use by Slice Machine configured through
Expand Down
1 change: 1 addition & 0 deletions test/module-options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ it('exposes options in runtime config', () => {
"clientConfig": {},
"components": {},
"endpoint": "qwerty",
"environment": "",
"injectComponents": true,
"linkResolver": "~/app/prismic/linkResolver",
"preview": "/preview",
Expand Down
21 changes: 19 additions & 2 deletions test/module-validate.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { it, expect, vi, afterEach } from 'vitest'
import mockFS from 'mock-fs'

import prismicModule from '../src/module'
import { logger } from '../src/lib/logger'
Expand All @@ -20,9 +21,25 @@ afterEach(() => {
vi.clearAllMocks()
})

it('warns and returns early if endpoint if not provided', () => {
it('warns and returns early if endpoint is not provided, and client file is not available, and runtime config environment variables aren\'t set', () => {
mockedPrismicModule()

expect(logger.warn).toHaveBeenCalledOnce()
expect(logger.warn).toHaveBeenCalledWith('Options `endpoint` is required, disabling module...')
expect(logger.warn).toHaveBeenCalledWith('`endpoint` option is missing and `~/app/prismic/client` was not found. At least one of them is required for the module to run. Disabling module...')
})

it('doesn\'t warn and return early if endpoint is provided', () => {
mockedPrismicModule({ endpoint: 'qwerty' })

expect(logger.warn).not.toHaveBeenCalled()
})

it('doesn\'t warn and return early if client file is provided', () => {
mockFS({
'/tmp/nuxt/app/prismic/client.ts': ''
})

mockedPrismicModule({ endpoint: 'qwerty' })

expect(logger.warn).not.toHaveBeenCalled()
})

0 comments on commit 0eb67c1

Please sign in to comment.