diff --git a/buildModules/tool-config/index.ts b/buildModules/tool-config/index.ts new file mode 100644 index 00000000..2dd7e0d2 --- /dev/null +++ b/buildModules/tool-config/index.ts @@ -0,0 +1,85 @@ +import {readdirSync, readFileSync} from 'fs' +import path, {join} from 'path' +import {Module} from '@nuxt/types' +import {NuxtRouteConfig} from '@nuxt/types/config/router' +import YAML from 'yaml' +import {capitalise} from '../../utils/string' + +const toolDirName = 'tools' +const rootDir = join(__dirname, '..', '..') +const toolsDir = join(rootDir, toolDirName) + +interface toolConfigModuleOptions { +} + +function getTools() { + const categories = readdirSync(toolsDir) + const toolList: { [key: string]: any[] } = {} + + for (const category of categories) { + const categoryDir = join(toolsDir, category) + const categoryFormatted = capitalise(category) + + toolList[categoryFormatted] = readdirSync(categoryDir).map((toolFileName) => { + const toolPath = join(categoryDir, toolFileName) + const contentMatch = readFileSync(toolPath, 'utf8').match(/\s]*)*>([\S\s.]*?)<\/tool>/) + + return contentMatch + ? { + ...YAML.parse(contentMatch[2]), + componentPath: join(toolDirName, category, toolFileName) + } + : null + }).filter(v => v !== null) + } + + return toolList +} + +const toolConfigModule: Module = function () { + const {nuxt, extendBuild, addPlugin} = this + const toolList = getTools() + const toolListFlat = Object.values(toolList).flat() + + nuxt.hook('build:extendRoutes', (routes: NuxtRouteConfig[]) => { + toolListFlat.forEach((toolConfig) => { + const {path = '', title, componentPath} = toolConfig + const name = title.toLowerCase().split(/\s/).join('-').replace(/\.vue$/, '') + + const newRoute: NuxtRouteConfig = { + name, + path, + component: join(rootDir, componentPath), + chunkName: componentPath.replace(/\.vue$/, '') + } + + routes.push(newRoute) + }) + + nuxt.options.publicRuntimeConfig.toolList = toolList + }) + + extendBuild((config) => { + if (!config.module) { + // eslint-disable-next-line no-console + console.warn('Failed to register the tool-config module.') + return + } + + config.module.rules.push({ + resourceQuery: /blockType=tool/, + loader: require.resolve('./loader.js') + }) + }) + + addPlugin({ + src: path.resolve(__dirname, 'plugin.ts'), + fileName: 'tool-config/plugin.ts', + options: { + toolList, + toolListFlat + } + }) +} + +export default toolConfigModule diff --git a/buildModules/tool-config/loader.js b/buildModules/tool-config/loader.js new file mode 100644 index 00000000..159c440d --- /dev/null +++ b/buildModules/tool-config/loader.js @@ -0,0 +1,13 @@ +const YAML = require('yaml') + +const loader = function (source, map) { + this.callback( + null, + `export default function (Component) { + Component.options.__toolConfig = ${JSON.stringify(YAML.parse(source))} + }`, + map + ) +} + +module.exports = loader diff --git a/buildModules/tool-config/plugin.ts b/buildModules/tool-config/plugin.ts new file mode 100644 index 00000000..00f3661b --- /dev/null +++ b/buildModules/tool-config/plugin.ts @@ -0,0 +1,16 @@ +// @ts-nocheck +import {Plugin} from '@nuxt/types' +import type {ToolRouteConfig} from '~/types/ToolConfig'; + +declare module 'vue/types/vue' { + interface Vue { + $toolListFlat: ToolRouteConfig[] + $toolList: { [key: string]: ToolRouteConfig[] } + } +} + +const plugin: Plugin = (_, inject) => { + inject('toolListFlat', <%= serialize(options.toolListFlat) %>) + inject('toolList', <%= serialize(options.toolList) %>) +} +export default plugin diff --git a/components/Memo.vue b/components/Memo.vue index 4910710d..10ce3078 100644 --- a/components/Memo.vue +++ b/components/Memo.vue @@ -1,6 +1,6 @@ diff --git a/static/icon.png b/static/icon.png new file mode 100644 index 00000000..84f1f340 Binary files /dev/null and b/static/icon.png differ diff --git a/pages/tools/converter/base-converter.vue b/tools/converter/base-converter.vue similarity index 92% rename from pages/tools/converter/base-converter.vue rename to tools/converter/base-converter.vue index ad84a509..053b161f 100644 --- a/pages/tools/converter/base-converter.vue +++ b/tools/converter/base-converter.vue @@ -1,5 +1,5 @@ + +title: 'Base converter' +description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.' +icon: 'mdi-swap-horizontal' +keywords: ['base', 'converter'] +path: '/color-picker-converter' + + diff --git a/pages/tools/sys-admin/crontab-generator.vue b/tools/sys-admin/crontab-generator.vue similarity index 92% rename from pages/tools/sys-admin/crontab-generator.vue rename to tools/sys-admin/crontab-generator.vue index 7df1407d..9ad0931e 100644 --- a/pages/tools/sys-admin/crontab-generator.vue +++ b/tools/sys-admin/crontab-generator.vue @@ -1,5 +1,5 @@ + +title: 'Crontab generator' +description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.' +icon: 'mdi-calendar-clock' +keywords: ['year', 'month', 'week', 'day', 'minute', 'second'] +path: '/crontab-generator' + +