diff options
author | 2022-04-14 02:02:05 +0200 | |
---|---|---|
committer | 2022-04-14 02:02:05 +0200 | |
commit | 358ff45ae1d9822b8a7c342515f668d25b7128b5 (patch) | |
tree | 640eaa6226ac5d6d5a92234576aa0c77a8283231 | |
parent | 24ff6528f72929d5aa1730e9f5015432fc99829f (diff) | |
download | it-tools-358ff45ae1d9822b8a7c342515f668d25b7128b5.tar.gz it-tools-358ff45ae1d9822b8a7c342515f668d25b7128b5.tar.zst it-tools-358ff45ae1d9822b8a7c342515f668d25b7128b5.zip |
feat(tool): crontab generator
-rw-r--r-- | package-lock.json | 22 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/plugins/naive.plugin.ts | 2 | ||||
-rw-r--r-- | src/tools/crontab-generator/crontab-generator.vue | 216 | ||||
-rw-r--r-- | src/tools/crontab-generator/index.ts | 11 | ||||
-rw-r--r-- | src/tools/index.ts | 3 |
6 files changed, 255 insertions, 1 deletions
diff --git a/package-lock.json b/package-lock.json index a6527e7..452c16d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,8 @@ "@vueuse/head": "^0.7.5", "bip39": "^3.0.4", "buffer": "^6.0.3", + "cron-validator": "^1.3.1", + "cronstrue": "^2.2.0", "crypto-js": "^4.1.1", "date-fns": "^2.28.0", "lodash": "^4.17.21", @@ -2383,6 +2385,16 @@ "sha.js": "^2.4.8" } }, + "node_modules/cron-validator": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cron-validator/-/cron-validator-1.3.1.tgz", + "integrity": "sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==" + }, + "node_modules/cronstrue": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.2.0.tgz", + "integrity": "sha512-oM/ftAvCNIdygVGGfYp8gxrVc81mDSA2mff0kvu6+ehrZhfYPzGHG8DVcFdrRVizjHnzWoFIlgEq6KTM/9lPBw==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -9925,6 +9937,16 @@ "sha.js": "^2.4.8" } }, + "cron-validator": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cron-validator/-/cron-validator-1.3.1.tgz", + "integrity": "sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==" + }, + "cronstrue": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.2.0.tgz", + "integrity": "sha512-oM/ftAvCNIdygVGGfYp8gxrVc81mDSA2mff0kvu6+ehrZhfYPzGHG8DVcFdrRVizjHnzWoFIlgEq6KTM/9lPBw==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/package.json b/package.json index 2461305..6b66aed 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "@vueuse/head": "^0.7.5", "bip39": "^3.0.4", "buffer": "^6.0.3", + "cron-validator": "^1.3.1", + "cronstrue": "^2.2.0", "crypto-js": "^4.1.1", "date-fns": "^2.28.0", "lodash": "^4.17.21", diff --git a/src/plugins/naive.plugin.ts b/src/plugins/naive.plugin.ts index 8b3e009..68d2036 100644 --- a/src/plugins/naive.plugin.ts +++ b/src/plugins/naive.plugin.ts @@ -45,9 +45,11 @@ import { NInputGroupLabel, NDivider, NStatistic, + NTable, } from 'naive-ui'; const components = [ + NTable, NStatistic, NDivider, NInputGroup, diff --git a/src/tools/crontab-generator/crontab-generator.vue b/src/tools/crontab-generator/crontab-generator.vue new file mode 100644 index 0000000..a77a3f5 --- /dev/null +++ b/src/tools/crontab-generator/crontab-generator.vue @@ -0,0 +1,216 @@ +<template> + <n-card> + <n-form-item class="cron" :show-label="false" :feedback="cronValidation.message" + :validation-status="cronValidation.status"> + <n-input v-model:value="cron" size="large" placeholder="* * * * *" /> + </n-form-item> + <div class="cron-string"> + {{ cronString }} + </div> + + <n-divider /> + + <n-space justify="center"> + + <n-form :show-feedback="false" label-width="170" label-placement="left"> + <n-form-item label="Verbose"> + <n-switch v-model:value="cronstrueConfig.verbose" /> + </n-form-item> + <n-form-item label="Use 24 hour time format"> + <n-switch v-model:value="cronstrueConfig.use24HourTimeFormat" /> + </n-form-item> + <n-form-item label="Days start at 0"> + <n-switch v-model:value="cronstrueConfig.dayOfWeekStartIndexZero" /> + </n-form-item> + </n-form> + </n-space> + </n-card> + <br> + <n-card> + <pre> +┌──────────── [optional] seconds (0 - 59) +| ┌────────── minute (0 - 59) +| | ┌──────── hour (0 - 23) +| | | ┌────── day of month (1 - 31) +| | | | ┌──── month (1 - 12) OR jan,feb,mar,apr ... +| | | | | ┌── day of week (0 - 6, sunday=0) OR sun,mon ... +| | | | | | +* * * * * * command</pre> + + + <n-table size="small"> + <thead> + <tr> + <th class="text-left" scope="col"> + Symbol + </th> + <th class="text-left" scope="col"> + Meaning + </th> + <th class="text-left" scope="col"> + Example + </th> + <th class="text-left" scope="col"> + Equivalent + </th> + </tr> + </thead> + <tbody> + <tr> + <td>*</td> + <td>Any value</td> + <td> + <code>* * * *</code> + </td> + <td>Every minute</td> + </tr> + <tr> + <td>-</td> + <td>Range of values</td> + <td> + <code>1-10 * * *</code> + </td> + <td>Minutes 1 through 10</td> + </tr> + <tr> + <td>,</td> + <td>List of values</td> + <td> + <code>1,10 * * *</code> + </td> + <td>At minutes 1 and 10</td> + </tr> + <tr> + <td>/</td> + <td>Step values</td> + <td> + <code>*/10 * * *</code> + </td> + <td>Every 10 minutes</td> + </tr> + <tr> + <td>@yearly</td> + <td>Once every year at midnight of 1 January</td> + <td> + <code>@yearly</code> + </td> + <td>0 0 1 1 *</td> + </tr> + <tr> + <td>@annually</td> + <td>Same as @yearly</td> + <td> + <code>@annually</code> + </td> + <td>0 0 1 1 *</td> + </tr> + <tr> + <td>@monthly</td> + <td>Once a month at midnight on the first day</td> + <td> + <code>@monthly</code> + </td> + <td>0 0 1 * *</td> + </tr> + <tr> + <td>@weekly</td> + <td>Once a week at midnight on Sunday morning</td> + <td> + <code>@weekly</code> + </td> + <td>0 0 * * 0</td> + </tr> + <tr> + <td>@daily</td> + <td>Once a day at midnight</td> + <td> + <code>@daily</code> + </td> + <td>0 0 * * *</td> + </tr> + <tr> + <td>@midnight</td> + <td>Same as @daily</td> + <td> + <code>@midnight</code> + </td> + <td>0 0 * * *</td> + </tr> + <tr> + <td>@hourly</td> + <td>Once an hour at the beginning of the hour</td> + <td> + <code>@hourly</code> + </td> + <td>0 * * * *</td> + </tr> + <tr> + <td>@reboot</td> + <td>Run at startup</td> + <td /> + <td /> + </tr> + </tbody> + </n-table> + + </n-card> +</template> + +<script setup lang="ts"> +import cronstrue from 'cronstrue' +import { isValidCron } from 'cron-validator' +import { computed, reactive, ref } from 'vue'; +import { useValidation } from '@/composable/validation'; + + +function isCronValid(v: string) { + return isValidCron(v, { allowBlankDay: true, alias: true, seconds: true }) +} + +const cron = ref('40 * * * *') +const cronstrueConfig = reactive({ + verbose: true, + dayOfWeekStartIndexZero: true, + use24HourTimeFormat: true, + throwExceptionOnParseError: true +}) + +const cronString = computed(() => { + if (isCronValid(cron.value)) { + return cronstrue.toString(cron.value, cronstrueConfig) + } + return ' ' +}) + +const cronValidation = useValidation({ + source: cron, + rules: [{ + validator: (value) => isCronValid(value), + message: 'This cron is invalid' + }] +}) +</script> + +<style lang="less" scoped> +.cron { + text-align: center; + + margin: auto; + max-width: 400px; + display: block; + + .n-input { + font-size: 30px; + font-family: monospace; + padding: 5px; + + } +} + +.cron-string { + text-align: center; + font-size: 22px; + opacity: 0.8; + margin: 5px 0 15px; +} +</style>
\ No newline at end of file diff --git a/src/tools/crontab-generator/index.ts b/src/tools/crontab-generator/index.ts new file mode 100644 index 0000000..5628625 --- /dev/null +++ b/src/tools/crontab-generator/index.ts @@ -0,0 +1,11 @@ +import { Alarm } from '@vicons/tabler'; +import type { ITool } from './../Tool'; + +export const tool: ITool = { + name: 'Crontab generator', + path: '/crontab-generator', + description: 'Validate and generate crontab and get the human readable description of the cron schedule.', + keywords: ['crontab', 'generator', 'cronjob', 'cron', 'schedule', 'parse', 'expression', 'year', 'month', 'week', 'day', 'minute', 'second'], + component: () => import('./crontab-generator.vue'), + icon: Alarm, +}; diff --git a/src/tools/index.ts b/src/tools/index.ts index d744353..17f7359 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,6 +1,7 @@ import { LockOpen } from '@vicons/tabler'; import type { ToolCategory } from './Tool'; +import { tool as crontabGenerator } from './crontab-generator'; import { tool as textStatistics } from './text-statistics'; import { tool as tokenGenerator } from './token-generator'; import { tool as hashText } from './hash-text'; @@ -34,7 +35,7 @@ export const toolsByCategory: ToolCategory[] = [ { name: 'Development', icon: LockOpen, - components: [gitMemo, randomPortGenerator], + components: [gitMemo, randomPortGenerator, crontabGenerator], }, { name: 'Text', |