mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-21 15:26:15 -04:00
feat: externalized tool configuration
This commit is contained in:
parent
c3adfe30ec
commit
690bd099ef
31 changed files with 387 additions and 300 deletions
85
buildModules/tool-config/index.ts
Normal file
85
buildModules/tool-config/index.ts
Normal file
|
@ -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(/<tool(\s[^>\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<toolConfigModuleOptions> = 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
|
13
buildModules/tool-config/loader.js
Normal file
13
buildModules/tool-config/loader.js
Normal file
|
@ -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
|
16
buildModules/tool-config/plugin.ts
Normal file
16
buildModules/tool-config/plugin.ts
Normal file
|
@ -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
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="memo">
|
||||
<ToolHeader :config="memoConfig" />
|
||||
<ToolHeader :config="$toolConfig" />
|
||||
|
||||
Warning: le style/aspect est toujours en wip, so focus on content <br><br>
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
append-icon="mdi-magnify"
|
||||
color="white"
|
||||
hide-details
|
||||
:items="toolRoutesFlat"
|
||||
:item-text="item => item.config.title"
|
||||
:items="$toolListFlat"
|
||||
:item-text="item => item.title"
|
||||
item-value="path"
|
||||
solo-inverted
|
||||
dense
|
||||
|
@ -26,12 +26,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, mixins} from 'nuxt-property-decorator'
|
||||
import {ToolRoutesMixin} from '@/mixins/tool-routes.mixin'
|
||||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
import {ToolRouteConfig} from '~/types/ToolConfig'
|
||||
|
||||
@Component
|
||||
export default class SearchBar extends mixins(ToolRoutesMixin) {
|
||||
export default class SearchBar extends Vue {
|
||||
choose(path:string) {
|
||||
this.$router.push({path})
|
||||
}
|
||||
|
@ -39,7 +38,7 @@ export default class SearchBar extends mixins(ToolRoutesMixin) {
|
|||
filterItems(item:ToolRouteConfig, queryText:string, itemText:string) {
|
||||
const query = queryText.trim().toLowerCase()
|
||||
const nameContainsText = itemText.toLowerCase().includes(query)
|
||||
const keywordContainsText = item?.config?.keywords.join(' ').toLowerCase().includes(query) ?? false
|
||||
const keywordContainsText = item?.keywords.join(' ').toLowerCase().includes(query) ?? false
|
||||
return nameContainsText || keywordContainsText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
<script lang="ts">
|
||||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
import {Component, mixins} from 'nuxt-property-decorator'
|
||||
import ToolWrapper from '~/components/ToolWrapper.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {ToolConfigMixin} from '~/mixins/tool-config.mixin'
|
||||
|
||||
@Component({components: {ToolWrapper}})
|
||||
export default class Tool extends Vue {
|
||||
@Component({
|
||||
components: {ToolWrapper}
|
||||
})
|
||||
export default class Tool extends mixins(ToolConfigMixin) {
|
||||
config(): ToolConfig {
|
||||
throw new Error('You need to specify a config() method your custom Tool.')
|
||||
return {
|
||||
title: 'ADD A <tool> TAG'
|
||||
} as unknown as ToolConfig
|
||||
};
|
||||
|
||||
public head() {
|
||||
const {title, description, keywords} = this.config()
|
||||
const {title, description, keywords} = this.$toolConfig
|
||||
|
||||
const uniqueKeywordsCleaned = [...new Set([...keywords, ...title.split(/\s+/)].map(s => s.trim().toLowerCase()))]
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<SearchBar class="hidden-sm-and-up" />
|
||||
|
||||
<v-list>
|
||||
<div v-for="(items, section) in toolRoutesSections" :key="section">
|
||||
<div v-for="(items, section) in $toolList" :key="section">
|
||||
<v-subheader class="mt-4 pl-4">
|
||||
{{ section }}
|
||||
</v-subheader>
|
||||
|
@ -37,11 +37,11 @@
|
|||
>
|
||||
<v-list-item-action>
|
||||
<v-icon color="primary">
|
||||
{{ item.config.icon }}
|
||||
{{ item.icon }}
|
||||
</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.config.title" />
|
||||
<v-list-item-title v-text="item.title" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</div>
|
||||
|
@ -103,9 +103,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, mixins} from 'nuxt-property-decorator'
|
||||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
import {version} from '../package.json'
|
||||
import {ToolRoutesMixin} from '~/mixins/tool-routes.mixin'
|
||||
import LogoOutlined from '~/assets/logo-outlined.svg?inline'
|
||||
import HeroGradient from '~/assets/small-hero-gradient.svg?inline'
|
||||
import SearchBar from '~/components/SearchBar.vue'
|
||||
|
@ -117,7 +116,7 @@ import SearchBar from '~/components/SearchBar.vue'
|
|||
SearchBar
|
||||
}
|
||||
})
|
||||
export default class DefaultLayout extends mixins(ToolRoutesMixin) {
|
||||
export default class DefaultLayout extends Vue {
|
||||
title = 'IT - Tools'
|
||||
drawer = false
|
||||
items = []
|
||||
|
|
12
mixins/tool-config.mixin.ts
Normal file
12
mixins/tool-config.mixin.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
import {ToolConfig} from '~/types/ToolConfig'
|
||||
|
||||
@Component
|
||||
export class ToolConfigMixin extends Vue {
|
||||
public $toolConfig!: ToolConfig;
|
||||
|
||||
beforeCreate() {
|
||||
// @ts-ignore
|
||||
this.$toolConfig = this.$options.__toolConfig
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
import {ToolRouteConfig} from '~/types/ToolConfig'
|
||||
import {capitalise} from '~/utils/string'
|
||||
|
||||
|
||||
@Component
|
||||
export class ToolRoutesMixin extends Vue {
|
||||
toolRoutesFlat : ToolRouteConfig[] = []
|
||||
toolRoutesSections : {[key: string]: ToolRouteConfig[]} = {}
|
||||
|
||||
async created() {
|
||||
const routes = this.$router.options.routes?.filter((r1, i, a) => r1.meta?.isTool && a.findIndex(r2 => r2.path.split('/').pop() === r1.path.split('/').pop()) === i) || []
|
||||
const flat: ToolRouteConfig[] = []
|
||||
const sections: { [key: string]: ToolRouteConfig[] } = {}
|
||||
|
||||
for (const route of routes) {
|
||||
if ('component' in route) {
|
||||
// @ts-ignore
|
||||
const component = await route.component()
|
||||
|
||||
const routeConfig = {...route, config: component.options.methods.config()} as ToolRouteConfig
|
||||
flat.push(routeConfig)
|
||||
|
||||
const sectionKey = capitalise(route.meta.section).replace(/_/g, ' ')
|
||||
|
||||
if (!(sectionKey in sections)) {
|
||||
sections[sectionKey] = []
|
||||
}
|
||||
|
||||
sections[sectionKey].push(routeConfig)
|
||||
}
|
||||
}
|
||||
|
||||
this.toolRoutesSections = sections
|
||||
this.toolRoutesFlat = flat
|
||||
}
|
||||
}
|
|
@ -36,7 +36,9 @@ export default {
|
|||
// https://go.nuxtjs.dev/typescript
|
||||
'@nuxt/typescript-build',
|
||||
// https://go.nuxtjs.dev/vuetify
|
||||
'@nuxtjs/vuetify'
|
||||
'@nuxtjs/vuetify',
|
||||
// '@nuxtjs/router-extras'
|
||||
'~/buildModules/tool-config'
|
||||
],
|
||||
|
||||
// Modules (https://go.nuxtjs.dev/config-modules)
|
||||
|
@ -48,6 +50,8 @@ export default {
|
|||
'@nuxtjs/svg',
|
||||
'nuxt-i18n',
|
||||
'@nuxtjs/markdownit'
|
||||
// '~/buildModules/tool-config'
|
||||
|
||||
],
|
||||
|
||||
// Axios module configuration (https://go.nuxtjs.dev/config-axios)
|
||||
|
|
92
package-lock.json
generated
92
package-lock.json
generated
|
@ -3583,15 +3583,6 @@
|
|||
"typescript": "~4.2"
|
||||
}
|
||||
},
|
||||
"@nuxt/typescript-runtime": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/typescript-runtime/-/typescript-runtime-2.1.0.tgz",
|
||||
"integrity": "sha512-quzxXiWq+jGdnCedDIYuBiExrfIJL3VL9o4gJyq6QzthKLYSvLzB6w4RiH6UbLtnNJyDoO9ywyNSI2+RUJr/Ng==",
|
||||
"requires": {
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "~4.2"
|
||||
}
|
||||
},
|
||||
"@nuxt/utils": {
|
||||
"version": "2.15.6",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/utils/-/utils-2.15.6.tgz",
|
||||
|
@ -4499,6 +4490,16 @@
|
|||
"workbox-cdn": "^5.1.4"
|
||||
}
|
||||
},
|
||||
"@nuxtjs/router-extras": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@nuxtjs/router-extras/-/router-extras-1.1.1.tgz",
|
||||
"integrity": "sha512-WUBT6ig0MweXZVC3bYbhQ6cxvIRLBCCcIy/nZxUEw1zAWwrPWX12l3b5zRTLDFVhGUQfio25GWkNh8UWHWK7kw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chokidar": "^3.4.3",
|
||||
"gray-matter": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"@nuxtjs/svg": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@nuxtjs/svg/-/svg-0.1.12.tgz",
|
||||
|
@ -5842,11 +5843,6 @@
|
|||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
|
@ -8302,11 +8298,6 @@
|
|||
"resolved": "https://registry.npmjs.org/devalue/-/devalue-2.0.1.tgz",
|
||||
"integrity": "sha512-I2TiqT5iWBEyB8GRfTDP0hiLZ0YeDJZ+upDxjBfOC2lebO5LezQMv7QvIUTzdb64jQyAKLf1AHADtGN+jw6v8Q=="
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
|
||||
},
|
||||
"diff-sequences": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
|
||||
|
@ -10251,6 +10242,18 @@
|
|||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
|
||||
},
|
||||
"gray-matter": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
|
||||
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-yaml": "^3.13.1",
|
||||
"kind-of": "^6.0.2",
|
||||
"section-matter": "^1.0.0",
|
||||
"strip-bom-string": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"growly": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
|
||||
|
@ -13152,7 +13155,8 @@
|
|||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"makeerror": {
|
||||
"version": "1.0.11",
|
||||
|
@ -16775,6 +16779,27 @@
|
|||
"resolved": "https://registry.npmjs.org/scule/-/scule-0.2.1.tgz",
|
||||
"integrity": "sha512-M9gnWtn3J0W+UhJOHmBxBTwv8mZCan5i1Himp60t6vvZcor0wr+IM0URKmIglsWJ7bRujNAVVN77fp+uZaWoKg=="
|
||||
},
|
||||
"section-matter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"kind-of": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
|
@ -17427,6 +17452,12 @@
|
|||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-bom-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
|
||||
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
|
@ -18021,19 +18052,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
|
||||
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"ts-pnp": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
|
||||
|
@ -18161,7 +18179,8 @@
|
|||
"typescript": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
|
||||
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg=="
|
||||
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
|
||||
"dev": true
|
||||
},
|
||||
"ua-parser-js": {
|
||||
"version": "0.7.28",
|
||||
|
@ -19811,11 +19830,6 @@
|
|||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
|
||||
},
|
||||
"yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
|
10
package.json
10
package.json
|
@ -3,17 +3,16 @@
|
|||
"version": "2.0.0-beta.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"dev": "nuxt",
|
||||
"build": "npm run generate",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"lint:commit": "commitlint --from $(git rev-list --max-parents=0 HEAD)",
|
||||
"lint:js": "eslint --ext .js,.vue --ignore-path=.gitignore --max-warnings=0 .",
|
||||
"lint": "npm run lint:js && npm run lint:commit",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/typescript-runtime": "^2.1.0",
|
||||
"@nuxtjs/axios": "^5.13.5",
|
||||
"@nuxtjs/markdownit": "^2.0.0",
|
||||
"@nuxtjs/pwa": "^3.0.2",
|
||||
|
@ -57,6 +56,7 @@
|
|||
"less-loader": "^7.1.0",
|
||||
"nuxt-property-decorator": "^2.9.1",
|
||||
"ts-jest": "^26.5.6",
|
||||
"vue-jest": "^3.0.4"
|
||||
"vue-jest": "^3.0.4",
|
||||
"yaml": "^1.10.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="(items, section) in toolRoutesSections"
|
||||
v-for="(items, section) in $toolList"
|
||||
:key="section"
|
||||
cols="12"
|
||||
sm="12"
|
||||
|
@ -24,10 +24,10 @@
|
|||
exact
|
||||
>
|
||||
<v-list-item-action>
|
||||
<v-icon>{{ item.config.icon }}</v-icon>
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.config.title" />
|
||||
<v-list-item-title v-text="item.title" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
@ -40,11 +40,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {Component, mixins} from 'nuxt-property-decorator'
|
||||
import {ToolRoutesMixin} from '@/mixins/tool-routes.mixin'
|
||||
import {Component, Vue} from 'nuxt-property-decorator'
|
||||
|
||||
@Component
|
||||
export default class Index extends mixins(ToolRoutesMixin) {
|
||||
export default class Index extends Vue {
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
BIN
static/icon.png
Normal file
BIN
static/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="4">
|
||||
<v-text-field
|
||||
|
@ -50,12 +50,19 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
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'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {Component, Ref} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import {ToolConfig} from '~/types/ToolConfig'
|
||||
import type {VForm} from '~/types/VForm'
|
||||
|
||||
const convertBase = (value: string, fromBase: number, toBase: number) => {
|
||||
|
@ -83,15 +90,6 @@ const convertBase = (value: string, fromBase: number, toBase: number) => {
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class BaseConverter extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
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']
|
||||
}
|
||||
}
|
||||
|
||||
@Ref() readonly inputBaseRef!: VForm
|
||||
@Ref() readonly outputBaseRef!: VForm
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-textarea
|
||||
v-model="clearText"
|
||||
outlined
|
||||
|
@ -23,26 +23,24 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Base64 string converter'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-text-box-outline'
|
||||
keywords: ['base64', 'base', '64', 'converter']
|
||||
path: '/base64-string-converter'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {base64ToString, stringToBase64} from '~/utils/convert'
|
||||
|
||||
@Component({
|
||||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class Base64StringConverter extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Base64 string converter',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-text-box-outline',
|
||||
keywords: ['base64', 'base', '64', 'converter']
|
||||
}
|
||||
}
|
||||
|
||||
clearText = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.'
|
||||
|
||||
get base64Text() {
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row no-gutters align="center" align-content="center" justify="center">
|
||||
<v-col cols="12" sm="6" align="center">
|
||||
<v-color-picker
|
||||
|
@ -59,6 +59,14 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Color picker/converter'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-palette'
|
||||
keywords: ['rgb', 'hsl', 'hex', 'keyword', 'css', 'picker']
|
||||
path: '/color-picker-converter'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
|
@ -66,7 +74,6 @@ import colors from 'color-name'
|
|||
import convert from 'color-convert'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import {ToolConfig} from '~/types/ToolConfig'
|
||||
import type {VForm} from '~/types/VForm'
|
||||
|
||||
const required = (v: unknown) => !!v || 'A value is required'
|
||||
|
@ -75,15 +82,6 @@ const required = (v: unknown) => !!v || 'A value is required'
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class ColorPickerConverter extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Color picker/converter',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-palette',
|
||||
keywords: ['rgb', 'hsl', 'hex', 'keyword', 'css', 'picker']
|
||||
}
|
||||
}
|
||||
|
||||
rgbPicker = {
|
||||
r: 76,
|
||||
g: 175,
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row>
|
||||
<v-col md="3" sm="12" class="pt-0 pb-0">
|
||||
<div class="text-center">
|
||||
|
@ -49,26 +49,24 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Date/Time converter'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-calendar-range'
|
||||
keywords: ['date', 'time', 'converter', 'iso']
|
||||
path: '/date-converter'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import Tool from '@/components/Tool.vue'
|
||||
import {ToolConfig} from '@/types/ToolConfig'
|
||||
|
||||
@Component({
|
||||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class DateConverter extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Date/Time converter',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-calendar-range',
|
||||
keywords: ['date', 'time', 'converter', 'iso']
|
||||
}
|
||||
}
|
||||
|
||||
inputString = ''
|
||||
inputFormatterTitle: string | null = null
|
||||
useCurrentDate = true
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-select
|
||||
v-model="language"
|
||||
outlined
|
||||
|
@ -33,13 +33,20 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'BIP39 passphrase generator'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-message-text-lock-outline'
|
||||
keywords: ['BIP39', 'passphrase', 'generator']
|
||||
path: '/bip39-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import * as bip39 from 'bip39'
|
||||
import {shuffle} from '@/utils/string'
|
||||
import {Component, Ref} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import Tool from '@/components/Tool.vue'
|
||||
import {ToolConfig} from '@/types/ToolConfig'
|
||||
import type {VForm} from '~/types/VForm'
|
||||
|
||||
const getRandomBuffer = () => Buffer.from(shuffle('0123456789abcdef'.repeat(16)).substring(0, 32), 'hex')
|
||||
|
@ -48,15 +55,6 @@ const getRandomBuffer = () => Buffer.from(shuffle('0123456789abcdef'.repeat(16))
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class Bip39Generator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'BIP39 passphrase generator',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-message-text-lock-outline',
|
||||
keywords: ['BIP39', 'passphrase', 'generator']
|
||||
}
|
||||
}
|
||||
|
||||
@Ref() readonly entropyRef!: VForm
|
||||
@Ref() readonly passphraseRef!: VForm
|
||||
buffer = getRandomBuffer()
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row justify="center" align="center">
|
||||
<v-col cols="12" lg="8" md="12">
|
||||
<v-textarea
|
||||
|
@ -42,11 +42,18 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Cypher / uncypher text'
|
||||
description: 'Cypher and uncyfer text.'
|
||||
icon: 'mdi-lock-open'
|
||||
keywords: ['cypher', 'uncypher', 'text', 'AES', 'TripleDES', 'Rabbit', 'RabbitLegacy', 'RC4']
|
||||
path: '/cypher-uncyfer-text'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import Tool from '@/components/Tool.vue'
|
||||
import type {ToolConfig} from '@/types/ToolConfig'
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const algos = {
|
||||
|
@ -67,15 +74,6 @@ export default class CypherUncyferText extends Tool {
|
|||
decrypted = 'Lorem ipsum dolor sit amet.'
|
||||
encrypted = ''
|
||||
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Cypher / uncypher text',
|
||||
description: 'Cypher and uncyfer text.',
|
||||
icon: 'mdi-lock-open',
|
||||
keywords: ['cypher', 'uncypher', 'text', ...Object.keys(algos).map(s => s.toLowerCase())]
|
||||
}
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.encrypt()
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-textarea
|
||||
v-model="inputText"
|
||||
outlined
|
||||
|
@ -27,12 +27,20 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Hash text'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-script-text-play'
|
||||
keywords: ['hash', 'text', 'MD5', 'SHA1', 'SHA256', 'SHA224', 'SHA512', 'SHA384', 'SHA3', 'RIPEMD160']
|
||||
path: '/hash-text'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import CryptoJS from 'crypto-js'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
|
||||
const algos = {
|
||||
MD5: CryptoJS.MD5,
|
||||
SHA1: CryptoJS.SHA1,
|
||||
|
@ -48,15 +56,6 @@ const algos = {
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class HashText extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Hash text',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-script-text-play',
|
||||
keywords: ['hash', 'text', ...Object.keys(algos).map(s => s.toLowerCase())]
|
||||
}
|
||||
}
|
||||
|
||||
inputText = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.'
|
||||
algorithm: keyof typeof algos = 'SHA256'
|
||||
algorithms: typeof algos = algos
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row no-gutters>
|
||||
<v-col lg="6" md="12">
|
||||
<v-switch v-model="withLowercase" label="Lowercase (abc...)" />
|
||||
|
@ -26,10 +26,17 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Token generator'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-key-chain-variant'
|
||||
keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols']
|
||||
path: '/token-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import {shuffle} from '~/utils/string'
|
||||
|
||||
|
@ -42,15 +49,6 @@ const specials = '.,;:!?./-"\'#{([-|\\@)]=}*+'
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class TokenGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Token generator',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-key-chain-variant',
|
||||
keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols']
|
||||
}
|
||||
}
|
||||
|
||||
withNumbers = true;
|
||||
withLowercase = true;
|
||||
withUppercase = true;
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-text-field
|
||||
v-model.number="quantity"
|
||||
outlined
|
||||
|
@ -28,11 +28,18 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'UUIDs generator'
|
||||
description: 'A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems. '
|
||||
icon: 'mdi-fingerprint'
|
||||
keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity']
|
||||
path: '/uuid-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {Component, Ref, Watch} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import type {ToolConfig} from '@/types/ToolConfig'
|
||||
import { VTextField } from 'vuetify/lib'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
|
||||
|
@ -42,15 +49,6 @@ const generateUuid = () => '10000000-1000-4000-8000-100000000000'.replace(/[018]
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class UuidGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'UUIDs generator',
|
||||
description: 'A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems. ',
|
||||
icon: 'mdi-fingerprint',
|
||||
keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity']
|
||||
}
|
||||
}
|
||||
|
||||
@Ref() readonly quantityEl! : typeof VTextField
|
||||
token = ''
|
||||
quantity = 1
|
|
@ -1,18 +1,17 @@
|
|||
<tool>
|
||||
title: 'Git memo'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-git'
|
||||
keywords: ['git', 'memo', 'cheat', 'sheet']
|
||||
path: '/git-memo'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import type {ToolConfig} from '@/types/ToolConfig'
|
||||
import Memo from '~/components/Memo.vue'
|
||||
|
||||
@Component
|
||||
export default class GitMemo extends Memo {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Git memo',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-git',
|
||||
keywords: ['git', 'memo', 'cheat', 'sheet']
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<div class="result">
|
||||
{{ cronString }}
|
||||
</div>
|
||||
|
@ -162,27 +162,25 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
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'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import cronstrue from 'cronstrue'
|
||||
import {isValidCron} from 'cron-validator'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
|
||||
@Component({
|
||||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class CrontabGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
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']
|
||||
}
|
||||
}
|
||||
|
||||
cron = '* * * * *'
|
||||
cronstrueConfig = {
|
||||
verbose: true,
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-text-field
|
||||
v-model="port"
|
||||
outlined
|
||||
|
@ -18,11 +18,18 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Random port generator'
|
||||
description: 'Random port generator without the range of "known" ports (0-1023).'
|
||||
icon: 'mdi-lan-pending'
|
||||
keywords: ['system', 'port', 'lan']
|
||||
path: '/random-port-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import type {ToolConfig} from '@/types/ToolConfig'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import {randIntFromInterval} from '~/utils/random'
|
||||
|
||||
|
@ -32,15 +39,6 @@ const generatePort = () => randIntFromInterval(1024, 65535)
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class RandomPortGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Random port generator',
|
||||
description: 'Random port generator without the range of "known" ports (0-1023).',
|
||||
icon: 'mdi-lan-pending',
|
||||
keywords: ['system', 'port', 'lan']
|
||||
}
|
||||
}
|
||||
|
||||
port!: number
|
||||
|
||||
created() {
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-slider v-model="paragraphs" min="1" max="20" label="Paragraphs" thumb-label />
|
||||
<v-range-slider
|
||||
v-model="sentencePerParagraph"
|
||||
|
@ -35,11 +35,18 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Lorem ipsum generator'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-comment-text'
|
||||
keywords: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet']
|
||||
path: '/lorem-ipsum-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {randFromArray, randIntFromInterval} from '~/utils/random'
|
||||
|
||||
const vocabulary = ['a', 'ac', 'accumsan', 'ad', 'adipiscing', 'aenean', 'aliquam', 'aliquet', 'amet', 'ante', 'aptent', 'arcu', 'at', 'auctor', 'bibendum', 'blandit', 'class', 'commodo', 'condimentum', 'congue', 'consectetur', 'consequat', 'conubia', 'convallis', 'cras', 'cubilia', 'cum', 'curabitur', 'curae', 'dapibus', 'diam', 'dictum', 'dictumst', 'dignissim', 'dolor', 'donec', 'dui', 'duis', 'egestas', 'eget', 'eleifend', 'elementum', 'elit', 'enim', 'erat', 'eros', 'est', 'et', 'etiam', 'eu', 'euismod', 'facilisi', 'faucibus', 'felis', 'fermentum', 'feugiat', 'fringilla', 'fusce', 'gravida', 'habitant', 'habitasse', 'hac', 'hendrerit', 'himenaeos', 'iaculis', 'id', 'imperdiet', 'in', 'inceptos', 'integer', 'interdum', 'ipsum', 'justo', 'lacinia', 'lacus', 'laoreet', 'lectus', 'leo', 'ligula', 'litora', 'lobortis', 'lorem', 'luctus', 'maecenas', 'magna', 'magnis', 'malesuada', 'massa', 'mattis', 'mauris', 'metus', 'mi', 'molestie', 'mollis', 'montes', 'morbi', 'mus', 'nam', 'nascetur', 'natoque', 'nec', 'neque', 'netus', 'nisi', 'nisl', 'non', 'nostra', 'nulla', 'nullam', 'nunc', 'odio', 'orci', 'ornare', 'parturient', 'pellentesque', 'penatibus', 'per', 'pharetra', 'phasellus', 'placerat', 'platea', 'porta', 'porttitor', 'posuere', 'potenti', 'praesent', 'pretium', 'primis', 'proin', 'pulvinar', 'purus', 'quam', 'quis', 'quisque', 'rhoncus', 'ridiculus', 'risus', 'rutrum', 'sagittis', 'sapien', 'scelerisque', 'sed', 'sem', 'semper', 'senectus', 'sit', 'sociis', 'sociosqu', 'sodales', 'sollicitudin', 'suscipit', 'suspendisse', 'taciti', 'tellus', 'tempor', 'tempus', 'tincidunt', 'torquent', 'tortor', 'turpis', 'ullamcorper', 'ultrices', 'ultricies', 'urna', 'varius', 'vehicula', 'vel', 'velit', 'venenatis', 'vestibulum', 'vitae', 'vivamus', 'viverra', 'volutpat', 'vulputate']
|
||||
|
@ -54,15 +61,6 @@ const generateSentence = (length: number) => {
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class LoremIpsumGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Lorem ipsum generator',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-comment-text',
|
||||
keywords: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet']
|
||||
}
|
||||
}
|
||||
|
||||
paragraphs = 1
|
||||
sentencePerParagraph = [3, 8]
|
||||
wordPerSentence = [8, 15]
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-textarea
|
||||
v-model="text"
|
||||
outlined
|
||||
|
@ -8,7 +8,10 @@
|
|||
auto-grow
|
||||
/>
|
||||
|
||||
<div>{{ $toolListFlat }}</div>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Character count:</strong></td>
|
||||
<td>{{ textLength }}</td>
|
||||
|
@ -25,32 +28,34 @@
|
|||
<td><strong>Byte size:</strong></td>
|
||||
<td>{{ textSize }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'Text stats'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: mdi-text
|
||||
keywords: [ length, character, count ]
|
||||
path: '/text-stats'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {formatBytes} from '~/utils/convert'
|
||||
|
||||
@Component({
|
||||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class TextStats extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'Text stats',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-text',
|
||||
keywords: ['length', 'character', 'count']
|
||||
}
|
||||
}
|
||||
|
||||
text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'
|
||||
|
||||
created() {
|
||||
}
|
||||
|
||||
get textLength() {
|
||||
return this.text.length
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()" no-card="true">
|
||||
<ToolWrapper :config="$toolConfig" no-card="true">
|
||||
<FileUploader v-model="file" />
|
||||
|
||||
<div v-if="base64 || loading" class="mt-10">
|
||||
|
@ -25,11 +25,18 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'File to base64'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-file-link-outline'
|
||||
keywords: ['file', 'base64']
|
||||
path: '/file-to-base64'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Watch} from 'nuxt-property-decorator'
|
||||
import {CopyableMixin} from '@/mixins/copyable.mixin'
|
||||
import Tool from '@/components/Tool.vue'
|
||||
import type {ToolConfig} from '@/types/ToolConfig'
|
||||
import FileUploader from '~/components/FileUploader.vue'
|
||||
|
||||
@Component({
|
||||
|
@ -37,15 +44,6 @@ import FileUploader from '~/components/FileUploader.vue'
|
|||
components: {FileUploader}
|
||||
})
|
||||
export default class FileToBase64 extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'File to base64',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-file-link-outline',
|
||||
keywords: ['file', 'base64']
|
||||
}
|
||||
}
|
||||
|
||||
file: Blob | null = null
|
||||
loading = false
|
||||
base64 = ''
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ToolWrapper :config="config()">
|
||||
<ToolWrapper :config="$toolConfig">
|
||||
<v-row justify="center" align="center">
|
||||
<v-col cols="12" lg="6" sm="12">
|
||||
<v-text-field
|
||||
|
@ -49,13 +49,20 @@
|
|||
</ToolWrapper>
|
||||
</template>
|
||||
|
||||
<tool>
|
||||
title: 'QR-code generator'
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.'
|
||||
icon: 'mdi-qrcode'
|
||||
keywords: ['editor']
|
||||
path: '/qrcode-generator'
|
||||
</tool>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component} from 'nuxt-property-decorator'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import colors from 'color-name'
|
||||
import {CopyableMixin} from '~/mixins/copyable.mixin'
|
||||
import Tool from '~/components/Tool.vue'
|
||||
import type {ToolConfig} from '~/types/ToolConfig'
|
||||
import {downloadBase64File} from '~/utils/file'
|
||||
import {stringToBase64} from '~/utils/convert'
|
||||
import ColorInput from '~/components/ColorInput.vue'
|
||||
|
@ -65,15 +72,6 @@ import ColorInput from '~/components/ColorInput.vue'
|
|||
mixins: [CopyableMixin]
|
||||
})
|
||||
export default class QrcodeGenerator extends Tool {
|
||||
config(): ToolConfig {
|
||||
return {
|
||||
title: 'QR-code generator',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.',
|
||||
icon: 'mdi-qrcode',
|
||||
keywords: ['editor']
|
||||
}
|
||||
}
|
||||
|
||||
value = 'https://it-tools.tech'
|
||||
size = 300
|
||||
level = 'M'
|
|
@ -1,13 +1,14 @@
|
|||
import {RouteConfig} from '@nuxt/types/config/router';
|
||||
|
||||
interface ToolConfig {
|
||||
title: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
keywords: string[];
|
||||
path?: string
|
||||
}
|
||||
|
||||
type ToolConfigMethod = () => ToolConfig;
|
||||
type ToolRouteConfig = RouteConfig & {config: ToolConfig}
|
||||
interface ToolRouteConfig extends ToolConfig{
|
||||
componentPath: string
|
||||
}
|
||||
|
||||
export {ToolConfig, ToolConfigMethod, ToolRouteConfig}
|
||||
export {ToolConfig, ToolRouteConfig}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue