diff --git a/packages/router/package.json b/packages/router/package.json index 97afb466d..afa4dc973 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -42,6 +42,7 @@ "templates" ], "dependencies": { + "@nuxt/kit": "^3.12.2", "druxt": "^0.24.0", "url-parse": "^1.5.10" }, diff --git a/packages/router/src/nuxt/index.js b/packages/router/src/nuxt/index.js index f2cbbe2e3..8d21b03d7 100644 --- a/packages/router/src/nuxt/index.js +++ b/packages/router/src/nuxt/index.js @@ -1,3 +1,4 @@ +import { addPluginTemplate, addTemplate, defineNuxtModule, extendPages, installModule } from '@nuxt/kit' import { existsSync } from 'fs' import { join, resolve } from 'path' import { DrupalJsonApiParams } from 'drupal-jsonapi-params' @@ -27,107 +28,122 @@ import { DruxtClient } from 'druxt' * @property {string} options.druxt.baseUrl - Base URL of Drupal JSON:API backend. * @property {string} options.druxt.router.component - File to custom Router component. */ -const DruxtRouterNuxtModule = async function (moduleOptions = {}) { - // Set default options. - const options = { - baseUrl: moduleOptions.baseUrl, - ...(this.options || {}).druxt || {}, - router: { - pages: (await existsSync(resolve(this.options.srcDir, this.options.dir.pages))), - wildcard: true, - ...((this.options || {}).druxt || {}).router, - ...moduleOptions, +const DruxtRouterNuxtModule = defineNuxtModule({ + meta: { + name: 'druxt-router', + }, + defaults: { + baseUrl: '', + endpoint: '/jsonapi', + }, + + async setup(moduleOptions, nuxt) { + // Set default options. + const options = { + baseUrl: moduleOptions.baseUrl, + ...nuxt.options?.druxt || {}, + router: { + pages: (await existsSync(resolve(nuxt.options.srcDir, nuxt.options.dir.pages))), + wildcard: true, + ...nuxt.options?.druxt?.router, + ...moduleOptions, + } } - } - // Add dependant modules. - await this.addModule(['druxt', options]) + // Add dependant modules. + await installModule('druxt/nuxt', options, nuxt) - // Register components directories. - this.nuxt.hook('components:dirs', dirs => { - dirs.push({ path: join(__dirname, '../dist/components') }) - }) + // Register components directories. + nuxt.hook('components:dirs', dirs => { + dirs.push({ path: join(__dirname, '../dist/components') }) + }) - // Add Druxt router custom wildcard route. - if (options.router.wildcard) { - // Ignore page routes. - if (!options.router.pages) { - this.nuxt.hook('build:before', () => - this.nuxt.options.build.createRoutes = () => [] - ) - } + // Add Druxt router custom wildcard route. + if (options.router.wildcard) { + // Ignore page routes. + if (!options.router.pages) { + nuxt.hook('build:before', () => + nuxt.options.build.createRoutes = () => [] + ) + } - // Add route template. - this.addTemplate({ - src: resolve(__dirname, '../templates/component.js'), - fileName: 'components/druxt-router.js', - options - }) + // Add route template. + addTemplate({ + src: resolve(__dirname, '../templates/component.js'), + fileName: 'components/druxt-router.js', + options, + write: true + }) - // Fetch languages. - let languages = [] - const druxt = new DruxtClient(options.baseUrl, { - ...options, - // Disable API Proxy, as Proxies aren't available at build. - proxy: { ...options.proxy || {}, api: false }, - }) - const languageResourceType = 'configurable_language--configurable_language' - if (((await druxt.getIndex(languageResourceType)) || {}).href) { - const query = new DrupalJsonApiParams().addFields(languageResourceType, ['drupal_internal__id']) - languages = (await druxt.getCollectionAll(languageResourceType, query) || []) - .map((o) => o.data) - .flat() - .filter((o) => !['und', 'zxx'].includes(((o || {}).attributes || {}).drupal_internal__id)) - } + // Fetch languages. + let languages = [] + const druxt = new DruxtClient(options.baseUrl, { + ...options, + // Disable API Proxy, as Proxies aren't available at build. + proxy: { ...options.proxy || {}, api: false }, + }) + const languageResourceType = 'configurable_language--configurable_language' + if (((await druxt.getIndex(languageResourceType)) || {}).href) { + const query = new DrupalJsonApiParams().addFields(languageResourceType, ['drupal_internal__id']) + languages = (await druxt.getCollectionAll(languageResourceType, query) || []) + .map((o) => o.data) + .flat() + .filter((o) => !['und', 'zxx'].includes(o?.attributes?.drupal_internal__id)) + } - // Extend routes. - this.extendRoutes((routes) => { - // Add route per language. - languages.filter((o) => o).forEach((o) => { + // Extend pages. + extendPages((routes) => { + // Add route per language. + languages.filter((o) => o).forEach((o) => { + routes.push({ + name: `druxt-router__${o.attributes.drupal_internal__id}`, + path: `/${o.attributes.drupal_internal__id}$/*`, + component: resolve(nuxt.options.buildDir, 'components/druxt-router.js'), + chunkName: 'druxt-router', + meta: { langcode: o.attributes.drupal_internal__id } + }) + }) + + // Add wildcard route. routes.push({ - name: `druxt-router__${o.attributes.drupal_internal__id}`, - path: `/${o.attributes.drupal_internal__id}*`, - component: resolve(this.options.buildDir, 'components/druxt-router.js'), - chunkName: 'druxt-router', - meta: { langcode: o.attributes.drupal_internal__id } + name: 'druxt-router', + path: '/*', + component: resolve(nuxt.options.buildDir, 'components/druxt-router.js'), + chunkName: 'druxt-router' }) }) + } - // Add wildcard route. - routes.push({ - name: 'druxt-router', - path: '*', - component: resolve(this.options.buildDir, 'components/druxt-router.js'), - chunkName: 'druxt-router' - }) + // Add plugin. + addPluginTemplate({ + src: resolve(__dirname, '../templates/plugin.js'), + fileName: 'druxt-router.js', + options }) - } - - // Add plugin. - this.addPlugin({ - src: resolve(__dirname, '../templates/plugin.js'), - fileName: 'druxt-router.js', - options - }) - - // Add Vuex plugin. - this.addPlugin({ - src: resolve(__dirname, '../templates/store.js'), - fileName: 'store/druxt-router.js', - options - }) - // Nuxt Storybook. - this.nuxt.hook('storybook:config', async ({ stories }) => { - this.addTemplate({ - src: resolve(__dirname, '../templates/druxt-router.stories.js'), - fileName: 'stories/druxt-router.stories.js', - options: {} + // Add store. + addPluginTemplate({ + src: resolve(__dirname, '../templates/store.js'), + fileName: 'store/druxt-router.js', + options: { + ...options + } }) - stories.push(resolve(this.options.buildDir, './stories/druxt-router.stories.js')) - }) -} -DruxtRouterNuxtModule.meta = require('../package.json') + // Enable Vuex Store. + nuxt.options.store = true + + // Nuxt Storybook. + // @TODO - @nuxt/kit and @nuxt/storybook aren't compatible. + // nuxt.hook('storybook:config', async ({ stories }) => { + // addTemplate({ + // src: resolve(__dirname, '../templates/druxt-router.stories.js'), + // fileName: 'stories/druxt-router.stories.js', + // options: {} + // }) + // stories.push(resolve(options.buildDir, './stories/druxt-router.stories.js')) + // }) + } +}) export default DruxtRouterNuxtModule