From 0b075d7eb11d4cc5e8ef6242b1700a95790a3c29 Mon Sep 17 00:00:00 2001 From: Stuart Clark Date: Tue, 27 Aug 2024 14:09:25 +1000 Subject: [PATCH] feat(#693): update druxt-menu for @nuxt/kit --- packages/menu/README.md | 2 +- packages/menu/package.json | 5 +- packages/menu/src/index.js | 23 +++--- packages/menu/src/nuxt/index.js | 81 +++++++++++++++++++ .../{nuxtStorybook.js => nuxt/storybook.js} | 0 packages/menu/src/nuxtModule.js | 71 ---------------- packages/menu/test/nuxt/index.test.js | 44 ++++++++++ .../storybook.test.js} | 2 +- packages/menu/test/nuxtModule.test.js | 43 ---------- 9 files changed, 140 insertions(+), 131 deletions(-) create mode 100644 packages/menu/src/nuxt/index.js rename packages/menu/src/{nuxtStorybook.js => nuxt/storybook.js} (100%) delete mode 100644 packages/menu/src/nuxtModule.js create mode 100644 packages/menu/test/nuxt/index.test.js rename packages/menu/test/{nuxtStorybook.test.js => nuxt/storybook.test.js} (86%) delete mode 100644 packages/menu/test/nuxtModule.test.js diff --git a/packages/menu/README.md b/packages/menu/README.md index e13f9883d..caf1e47ed 100644 --- a/packages/menu/README.md +++ b/packages/menu/README.md @@ -23,7 +23,7 @@ Add module to `nuxt.config.js` ```js module.exports = { - modules: ['druxt-menu'], + modules: ['druxt-menu/nuxt'], druxt: { baseUrl: 'https://demo-api.druxtjs.org', menu: { diff --git a/packages/menu/package.json b/packages/menu/package.json index ed43c1d55..6901eb55c 100644 --- a/packages/menu/package.json +++ b/packages/menu/package.json @@ -33,15 +33,18 @@ "require": "./dist/druxt-menu.ssr.js", "import": "./dist/druxt-menu.esm.js" }, - "./components/*": "./dist/components/*" + "./components/*": "./dist/components/*", + "./nuxt": "./nuxt/index.js" }, "main": "dist/druxt-menu.ssr.js", "module": "dist/druxt-menu.esm.js", "files": [ "dist", + "nuxt", "templates" ], "dependencies": { + "@nuxt/kit": "^3.12.2", "deepmerge": "^4.3.1", "drupal-jsonapi-params": "^2.3.1", "druxt": "^0.24.0", diff --git a/packages/menu/src/index.js b/packages/menu/src/index.js index e7f735181..b4111fc38 100644 --- a/packages/menu/src/index.js +++ b/packages/menu/src/index.js @@ -1,5 +1,3 @@ -import { DruxtMenuNuxtModule } from './nuxtModule' - /** * The DruxtMenu class. * @@ -22,18 +20,6 @@ export { DruxtMenu } from './menu.js' */ export { DruxtMenuStore } from './stores/menu.js' -/** - * The Nuxt.js module function. - * - * Installs the module functionality in a Nuxt application. - * - * @type {Function} - * @exports default - * @name DruxtMenuNuxtModule - * @see {@link ./nuxtModule|DruxtMenuNuxtModule} - */ -export default DruxtMenuNuxtModule - /** * Vue.js Mixin. * @@ -42,3 +28,12 @@ export default DruxtMenuNuxtModule * @see {@link ./mixins/menu|DruxtMenuMixin} */ export { DruxtMenuMixin } from './mixins/menu' + +/** + * Default function to alert user to incorrectly installed module. + * + * This was added as part of the @nuxt/kit update due to breaking changes. + */ +export default () => { + throw new Error("DruxtMenu Nuxt module must be installed as 'druxt-menu/nuxt'") +} diff --git a/packages/menu/src/nuxt/index.js b/packages/menu/src/nuxt/index.js new file mode 100644 index 000000000..f5d7113cc --- /dev/null +++ b/packages/menu/src/nuxt/index.js @@ -0,0 +1,81 @@ +import { addPluginTemplate, defineNuxtModule, installModule } from '@nuxt/kit' +import { join, resolve } from 'path' +// import DruxtMenuStorybook from './storybook' + +/** + * The Nuxt.js module function. + * + * - Adds Nuxt plugin. + * - Adds Vuex store. + * - Adds Nuxt Storybook integration. + * + * The module function should not be used directly, but rather installed via your Nuxt configuration file. + * + * Options are set on the root level `druxt` Nuxt config object. + * + * @example @lang js + * // `nuxt.config.js` + * module.exports = { + * modules: [ + * 'druxt-menu' + * ], + * druxt: { + * baseUrl: 'https://demo-api.druxtjs.org' + * } + * } + * + * @param {object} moduleOptions - Module options object. + */ +const DruxtMenuNuxtModule = defineNuxtModule({ + meta: { + name: 'druxt-menu', + }, + defaults: { + baseUrl: '', + endpoint: '/jsonapi' + }, + + async setup(moduleOptions, nuxt) { + // Set default options. + const options = { + baseUrl: moduleOptions.baseUrl, + ...nuxt.options?.druxt || {}, + menu: { + jsonApiMenuItems: true, + ...nuxt.options?.druxt?.menu, + ...moduleOptions, + } + } + + // Add dependant modules. + await installModule('druxt/nuxt', options) + + // Register components directories. + nuxt.hook('components:dirs', dirs => { + dirs.push({ path: join(__dirname, '../dist/components') }) + dirs.push({ path: join(__dirname, '../dist/components/blocks') }) + }) + + // Add plugin. + addPluginTemplate({ + src: resolve(__dirname, '../templates/plugin.js'), + fileName: 'druxt-menu.js', + options + }) + + // Add Vuex plugin. + addPluginTemplate({ + src: resolve(__dirname, '../templates/store.js'), + fileName: 'store/druxt-menu.js', + options + }) + + // Nuxt Storybook. + // @TODO - @nuxt/kit and @nuxt/storybook aren't compatible. + // this.nuxt.hook('storybook:config', async ({ stories }) => { + // await DruxtMenuStorybook.call(this, { stories }) + // }) + } +}) + +export default DruxtMenuNuxtModule diff --git a/packages/menu/src/nuxtStorybook.js b/packages/menu/src/nuxt/storybook.js similarity index 100% rename from packages/menu/src/nuxtStorybook.js rename to packages/menu/src/nuxt/storybook.js diff --git a/packages/menu/src/nuxtModule.js b/packages/menu/src/nuxtModule.js deleted file mode 100644 index 1661bb9fe..000000000 --- a/packages/menu/src/nuxtModule.js +++ /dev/null @@ -1,71 +0,0 @@ -import { join, resolve } from 'path' -import DruxtMenuStorybook from './nuxtStorybook' - -/** - * The Nuxt.js module function. - * - * - Adds Nuxt plugin. - * - Adds Vuex store. - * - Adds Nuxt Storybook integration. - * - * The module function should not be used directly, but rather installed via your Nuxt configuration file. - * - * Options are set on the root level `druxt` Nuxt config object. - * - * @example @lang js - * // `nuxt.config.js` - * module.exports = { - * modules: [ - * 'druxt-menu' - * ], - * druxt: { - * baseUrl: 'https://demo-api.druxtjs.org' - * } - * } - * - * @param {object} moduleOptions - Module options object. - */ -const DruxtMenuNuxtModule = async function (moduleOptions = {}) { - // Set default options. - const options = { - baseUrl: moduleOptions.baseUrl, - ...(this.options || {}).druxt || {}, - menu: { - jsonApiMenuItems: true, - ...((this.options || {}).druxt || {}).menu, - ...moduleOptions, - } - } - - // Add dependant modules. - await this.addModule(['druxt', options]) - - // Register components directories. - this.nuxt.hook('components:dirs', dirs => { - dirs.push({ path: join(__dirname, 'components') }) - dirs.push({ path: join(__dirname, 'components/blocks') }) - }) - - // Add plugin. - this.addPlugin({ - src: resolve(__dirname, '../templates/plugin.js'), - fileName: 'druxt-menu.js', - options - }) - - // Add Vuex plugin. - this.addPlugin({ - src: resolve(__dirname, '../templates/store.js'), - fileName: 'store/druxt-menu.js', - options - }) - - // Nuxt Storybook. - this.nuxt.hook('storybook:config', async ({ stories }) => { - await DruxtMenuStorybook.call(this, { stories }) - }) -} - -DruxtMenuNuxtModule.meta = require('../package.json') - -export { DruxtMenuNuxtModule } diff --git a/packages/menu/test/nuxt/index.test.js b/packages/menu/test/nuxt/index.test.js new file mode 100644 index 000000000..f88cb8890 --- /dev/null +++ b/packages/menu/test/nuxt/index.test.js @@ -0,0 +1,44 @@ +import DruxtMenuNuxtModule from '../../src/nuxt' + +jest.mock('../../src/nuxt/storybook') + +jest.mock('@nuxt/kit', () => ({ + addPluginTemplate: jest.fn(), + defineNuxtModule: (module) => module, + installModule: jest.fn(), +})) + +import { addPluginTemplate, installModule } from '@nuxt/kit' + +const nuxtMock = { + hook: jest.fn((hook, fn) => { + const arg = { + 'components:dirs': [], + 'storybook:config': { stories: [] } + } + return fn(arg[hook]) + }), +} + +test('Nuxt module', async () => { + // Use module with defaults. + await DruxtMenuNuxtModule.setup({}, nuxtMock) + expect(addPluginTemplate).toHaveBeenCalled() + + // Expect JSON:API Menu Items tp be enabled. + expect(installModule).toHaveBeenLastCalledWith('druxt/nuxt', { + baseUrl: undefined, + menu: { + jsonApiMenuItems: true + } + }) + + // Use overridden options; Drupal content menu items. + await DruxtMenuNuxtModule.setup({}, { ...nuxtMock, options: { druxt: { menu: { jsonApiMenuItems: false }}} }) + expect(installModule).toHaveBeenLastCalledWith('druxt/nuxt', { + baseUrl: undefined, + menu: { + jsonApiMenuItems: false + } + }) +}) diff --git a/packages/menu/test/nuxtStorybook.test.js b/packages/menu/test/nuxt/storybook.test.js similarity index 86% rename from packages/menu/test/nuxtStorybook.test.js rename to packages/menu/test/nuxt/storybook.test.js index 7f659896b..c961de7fb 100644 --- a/packages/menu/test/nuxtStorybook.test.js +++ b/packages/menu/test/nuxt/storybook.test.js @@ -1,4 +1,4 @@ -import DruxtMenuStorybook from '../src/nuxtStorybook' +import DruxtMenuStorybook from '../../src/nuxt/storybook' jest.mock('axios') diff --git a/packages/menu/test/nuxtModule.test.js b/packages/menu/test/nuxtModule.test.js deleted file mode 100644 index 4684133a1..000000000 --- a/packages/menu/test/nuxtModule.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import { DruxtMenuNuxtModule } from '../src/nuxtModule' - -jest.mock('../src/nuxtStorybook') - -const mock = { - addModule: jest.fn(), - addPlugin: jest.fn(), - nuxt: { - hook: jest.fn((hook, fn) => { - const arg = { - 'components:dirs': [], - 'storybook:config': { stories: [] } - } - return fn(arg[hook]) - }), - }, - options: { - druxt: {} - } -} - -test('Nuxt module', async () => { - // Use module with defaults. - await DruxtMenuNuxtModule.call(mock) - expect(mock.addPlugin).toHaveBeenCalled() - - // Expect JSON:API Menu Items tp be enabled. - expect(mock.addModule).toHaveBeenLastCalledWith(['druxt', { - baseUrl: undefined, - menu: { - jsonApiMenuItems: true - } - }]) - - // Use overridden options; Drupal content menu items. - await DruxtMenuNuxtModule.call({ ...mock, options: { druxt: { menu: { jsonApiMenuItems: false }}} }) - expect(mock.addModule).toHaveBeenLastCalledWith(['druxt', { - baseUrl: undefined, - menu: { - jsonApiMenuItems: false - } - }]) -})