mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
fix: let user choice 'standard' vs 'aws'
Let the user choose between cron format (since help is different)
This commit is contained in:
parent
8754d626e1
commit
fa01008dc8
4 changed files with 57 additions and 22 deletions
5
components.d.ts
vendored
5
components.d.ts
vendored
|
@ -135,13 +135,18 @@ declare module '@vue/runtime-core' {
|
|||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||
NDivider: typeof import('naive-ui')['NDivider']
|
||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||
NForm: typeof import('naive-ui')['NForm']
|
||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTable: typeof import('naive-ui')['NTable']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
|
|
|
@ -4,6 +4,7 @@ import { getCronType, getLastExecutionTimes, isCronValid } from './crontab-gener
|
|||
describe('crontab-generator', () => {
|
||||
describe('isCronValid', () => {
|
||||
it('should return true for all valid formats', () => {
|
||||
// standard format
|
||||
expect(isCronValid('0 0 * * 1-5')).toBe(true);
|
||||
expect(isCronValid('23 0-20/2 * * *')).toBe(true);
|
||||
|
||||
|
@ -11,6 +12,24 @@ describe('crontab-generator', () => {
|
|||
expect(isCronValid('0 11-22 ? * MON-FRI *')).toBe(true);
|
||||
expect(isCronValid('0 0 ? * 1 *')).toBe(true);
|
||||
});
|
||||
it('should check standard format', () => {
|
||||
// standard format
|
||||
expect(isCronValid('0 0 * * 1-5', 'standard')).toBe(true);
|
||||
expect(isCronValid('23 0-20/2 * * *', 'standard')).toBe(true);
|
||||
|
||||
// AWS format
|
||||
expect(isCronValid('0 11-22 ? * MON-FRI *', 'standard')).toBe(false);
|
||||
expect(isCronValid('0 0 ? * 1 *', 'standard')).toBe(false);
|
||||
});
|
||||
it('should check aws format', () => {
|
||||
// standard format
|
||||
expect(isCronValid('0 0 * * 1-5', 'aws')).toBe(false);
|
||||
expect(isCronValid('23 0-20/2 * * *', 'aws')).toBe(false);
|
||||
|
||||
// AWS format
|
||||
expect(isCronValid('0 11-22 ? * MON-FRI *', 'aws')).toBe(true);
|
||||
expect(isCronValid('0 0 ? * 1 *', 'aws')).toBe(true);
|
||||
});
|
||||
it('should return false for all invalid formats', () => {
|
||||
expect(isCronValid('aert')).toBe(false);
|
||||
expect(isCronValid('40 *')).toBe(false);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { parseExpression } from 'cron-parser';
|
||||
import EventCronParser from 'event-cron-parser';
|
||||
|
||||
export type CronType = 'standard' | 'aws';
|
||||
|
||||
export function getLastExecutionTimes(cronExpression: string, tz: string | undefined = undefined, count: number = 5) {
|
||||
if (getCronType(cronExpression) === 'standard') {
|
||||
const interval = parseExpression(cronExpression, { tz });
|
||||
|
@ -22,18 +24,19 @@ export function getLastExecutionTimes(cronExpression: string, tz: string | undef
|
|||
return [];
|
||||
}
|
||||
|
||||
export function isCronValid(v: string) {
|
||||
return !!getCronType(v);
|
||||
export function isCronValid(cronExpression: string, cronType: CronType | 'any' = 'any') {
|
||||
const expressionCronType = getCronType(cronExpression);
|
||||
return cronType === 'any' ? !!expressionCronType : expressionCronType === cronType;
|
||||
}
|
||||
|
||||
export function getCronType(v: string) {
|
||||
export function getCronType(cronExpression: string) {
|
||||
try {
|
||||
parseExpression(v);
|
||||
parseExpression(cronExpression);
|
||||
return 'standard';
|
||||
}
|
||||
catch (_) {
|
||||
try {
|
||||
const parsed = new EventCronParser(v);
|
||||
const parsed = new EventCronParser(cronExpression);
|
||||
parsed.validate();
|
||||
return 'aws';
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import cronstrue from 'cronstrue';
|
||||
import ctz from 'countries-and-timezones';
|
||||
import getTimezoneOffset from 'get-timezone-offset';
|
||||
import { getCronType, getLastExecutionTimes, isCronValid } from './crontab-generator.service';
|
||||
import { type CronType, getLastExecutionTimes, isCronValid } from './crontab-generator.service';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||
|
||||
|
@ -20,10 +20,13 @@ const cronstrueConfig = reactive({
|
|||
|
||||
// getTimezoneOffset(tz.name, now) / 60
|
||||
const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const allTimezones = Object.values(ctz.getAllTimezones()).map(tz => ({
|
||||
const allTimezones = Object.values(ctz.getAllTimezones()).map((tz) => {
|
||||
const timezoneUTCDSTOffset = tz.utcOffset === tz.dstOffset ? tz.utcOffsetStr : `${tz.utcOffsetStr}/${tz.dstOffsetStr}`;
|
||||
return {
|
||||
value: tz.name,
|
||||
label: `${tz.name === browserTimezone ? 'Browser TZ - ' : ''}${tz.name} (${tz.utcOffset === tz.dstOffset ? tz.utcOffsetStr : `${tz.utcOffsetStr}/${tz.dstOffsetStr}`})`,
|
||||
}));
|
||||
label: `${tz.name === browserTimezone ? 'Browser TZ - ' : ''}${tz.name} (${timezoneUTCDSTOffset})`,
|
||||
};
|
||||
});
|
||||
const currentTimezone = useQueryParamOrStorage({ name: 'tz', storageName: 'crongen:tz', defaultValue: browserTimezone });
|
||||
watchEffect(() => {
|
||||
cronstrueConfig.tzOffset = -getTimezoneOffset(currentTimezone.value, new Date()) / 60;
|
||||
|
@ -136,19 +139,24 @@ const awsHelpers = [
|
|||
},
|
||||
];
|
||||
|
||||
const cronType = computed({
|
||||
get() {
|
||||
return getCronType(cron.value);
|
||||
},
|
||||
set(newCronType) {
|
||||
const defaultAWSCronExpression = '0 0 ? * 1 *';
|
||||
const defaultStandardCronExpression = '40 * * * *';
|
||||
const cronType = ref<CronType>('standard');
|
||||
watch(cronType,
|
||||
(newCronType) => {
|
||||
if (newCronType === 'aws') {
|
||||
cron.value = '0 0 ? * 1 *';
|
||||
if (!cron.value || cron.value === defaultStandardCronExpression) {
|
||||
cron.value = defaultAWSCronExpression;
|
||||
}
|
||||
}
|
||||
else if (newCronType === 'standard') {
|
||||
if (!cron.value || cron.value === defaultAWSCronExpression) {
|
||||
cron.value = defaultStandardCronExpression;
|
||||
}
|
||||
else {
|
||||
cron.value = '40 * * * *';
|
||||
}
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
const getHelpers = computed(() => {
|
||||
if (cronType.value === 'aws') {
|
||||
return awsHelpers;
|
||||
|
@ -165,7 +173,7 @@ const cronString = computed(() => {
|
|||
|
||||
const cronValidationRules = [
|
||||
{
|
||||
validator: (value: string) => isCronValid(value),
|
||||
validator: (value: string) => isCronValid(value, cronType.value),
|
||||
message: 'This cron is invalid',
|
||||
},
|
||||
];
|
||||
|
@ -245,7 +253,7 @@ const executionTimesString = computed(() => {
|
|||
</c-card>
|
||||
<c-card>
|
||||
<pre v-if="cronType === 'standard'">
|
||||
-- Standard CRON Syntax --
|
||||
-- Standard CRON Syntax --
|
||||
┌──────────── [optional] seconds (0 - 59)
|
||||
| ┌────────── minute (0 - 59)
|
||||
| | ┌──────── hour (0 - 23)
|
||||
|
@ -256,7 +264,7 @@ const executionTimesString = computed(() => {
|
|||
* * * * * * command</pre>
|
||||
|
||||
<pre v-if="cronType === 'aws'">
|
||||
-- AWS CRON Syntax --
|
||||
-- AWS CRON Syntax --
|
||||
┌──────────── minute (0 - 59)
|
||||
| ┌────────── hour (0 - 23)
|
||||
| | ┌──────── day of month (1 - 31) OR ? OR L OR W
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue