UNPKG

@nuxtjs/prismic

Version:

Easily connect your Nuxt application to your content hosted on Prismic

303 lines (299 loc) 9.49 kB
import { existsSync } from 'node:fs'; import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { useLogger, defineNuxtModule, createResolver, addPlugin, addComponent, addImports, extendPages, getNuxtVersion, addTemplate } from '@nuxt/kit'; import { defu } from 'defu'; import { addDependency } from 'nypm'; import { readPackage } from 'pkg-types'; const name = "@nuxtjs/prismic"; const version = "5.2.0"; const logger = useLogger("nuxt:prismic"); async function addPrismicClient() { try { const pkg = await readPackage(); if (!pkg.dependencies?.["@prismicio/client"] && !pkg.devDependencies?.["@prismicio/client"]) { await addDependency("@prismicio/client"); logger.info("Added `@prismicio/client` required peer dependency"); } } catch { } } const module$1 = defineNuxtModule({ meta: { name, version, configKey: "prismic", compatibility: { nuxt: ">=3.7.0" } }, onInstall() { return addPrismicClient(); }, onUpgrade(_options, _nuxt, previousVersion) { const previousMajor = parseInt(previousVersion.split(".")[0]); if (previousMajor < 4) { return addPrismicClient(); } }, defaults: (nuxt) => { const nuxt3flavor = getNuxtVersion(nuxt).startsWith("3") && !nuxt.options?.future?.compatibilityVersion; if (nuxt3flavor) { return { endpoint: "", environment: "", clientConfig: {}, client: "~/app/prismic/client", linkResolver: "~/app/prismic/linkResolver", preview: "/preview", toolbar: true, imports: ["vue"], components: { richTextComponents: "~/app/prismic/richTextComponents " } }; } return { endpoint: "", environment: "", client: "~/prismic/client", linkResolver: "~/prismic/linkResolver", clientConfig: {}, preview: "/preview", toolbar: true, imports: ["vue"], components: { richTextComponents: "~/prismic/richTextComponents" } }; }, setup(options, nuxt) { const resolver = createResolver(import.meta.url); const moduleOptions = defu( nuxt.options.runtimeConfig.public?.prismic, options ); exposeRuntimeConfig(); transpileDependencies(); const ok = proxyUserFiles(); if (!ok) return; addRuntimePlugins(); addAutoImports(); addPreviewRoute(); extendESLintConfig(); function exposeRuntimeConfig() { nuxt.options.runtimeConfig.public ||= {}; nuxt.options.runtimeConfig.public.prismic = moduleOptions; } function transpileDependencies() { 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"); } function proxyUserFiles() { const proxyUserFileWithUndefinedFallback = (filename, path) => { const resolvedFilename = `prismic/proxy/${filename}.ts`; const resolvedPath = path.replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir); const maybeUserFile = fileExists(resolvedPath, [ "js", "mjs", "ts", "vue" ]); if (maybeUserFile) { 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}'` }); return true; } else { 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 false; } proxyUserFileWithUndefinedFallback( "linkResolver", moduleOptions.linkResolver ); proxyUserFileWithUndefinedFallback( "richTextComponents", moduleOptions.components.richTextComponents ); return true; } function addRuntimePlugins() { addPlugin(resolver.resolve("runtime/plugin")); addPlugin(resolver.resolve("runtime/plugin.client")); } function addAutoImports() { if (!moduleOptions.imports) return; if (moduleOptions.imports === "all" || moduleOptions.imports.includes("vue")) { [ "PrismicImage", "PrismicLink", "PrismicText", "PrismicRichText", "PrismicTable", "SliceZone", "SliceSimulator" ].forEach((entry) => { addComponent({ name: entry, export: entry, filePath: "@prismicio/vue" }); }); addImports( [ "usePrismic", "getSliceComponentProps", "defineSliceZoneComponents", "getRichTextComponentProps", "getTableComponentProps" ].map((entry) => ({ name: entry, as: entry, from: "@prismicio/vue" })) ); addImports({ name: "usePrismicPreview", as: "usePrismicPreview", from: resolver.resolve("runtime/usePrismicPreview") }); } if (moduleOptions.imports === "all" || moduleOptions.imports.includes("javascript")) { addImports( [ "asDate", "asLink", "asLinkAttrs", "asText", "asHTML", "asImageSrc", "asImageWidthSrcSet", "asImagePixelDensitySrcSet", "isFilled" ].map((entry) => ({ name: entry, as: entry, from: "@prismicio/client" })) ); } if (moduleOptions.imports === "all" || moduleOptions.imports.includes("content")) { addImports({ name: "Content", from: "@prismicio/client", typeFrom: "@prismicio/client", type: true }); } } function addPreviewRoute() { if (moduleOptions.preview) { const maybeUserPreviewPage = fileExists( join( nuxt.options.srcDir, nuxt.options.dir.pages, moduleOptions.preview ), ["js", "ts", "vue"] ); if (maybeUserPreviewPage) { logger.info( `Using user-defined preview page at \`${maybeUserPreviewPage.replace(join(nuxt.options.srcDir), "~").replace(nuxt.options.rootDir, "~~").replace( /\\/g, "/" )}\`, available at \`${moduleOptions.preview}\`` ); } else { logger.info( `Using default preview page, available at \`${moduleOptions.preview}\`` ); extendPages((pages) => { pages.unshift({ name: "prismic-preview", path: moduleOptions.preview, // Checked before file: resolver.resolve("runtime/PrismicPreview.vue") }); }); } if (!moduleOptions.toolbar) { logger.warn( "`toolbar` option is disabled but `preview` is enabled. Previews won't work unless you manually load the toolbar." ); } } } function extendESLintConfig() { nuxt.hook( // @ts-expect-error 3rd party hook "eslint:config:addons", (addons) => { addons.push({ name: "@nuxtjs/prismic", async getConfigs() { const configPath = resolver.resolve( nuxt.options.rootDir, "slicemachine.config.json" ); const configs = []; try { if (existsSync(configPath)) { const config = JSON.parse(await readFile(configPath, "utf-8")); if (config && "libraries" in config && Array.isArray(config.libraries)) { configs.push( JSON.stringify({ files: config.libraries.map( (library) => `${library.replace("./", "")}/**/index.vue` ), rules: { "vue/multi-word-component-names": "off" } }) ); } } } catch { } return { configs }; } }); } ); } } }); function fileExists(path, extensions = ["js", "ts"]) { if (!path) { return null; } else if (existsSync(path)) { return path; } const extension = extensions.find( (extension2) => existsSync(`${path}.${extension2}`) ); return extension ? `${path}.${extension}` : null; } export { module$1 as default };