cron-converter-u2q 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,100 +1,131 @@
1
1
  # cron-converter-u2q
2
2
 
3
- ![Github Repo Stars](https://img.shields.io/github/stars/rahu619/cron-converter-u2q?style=social)
3
+ [![Github Repo Stars](https://img.shields.io/github/stars/rahu619/cron-converter-u2q?style=social)](https://github.com/rahu619/cron-converter-u2q)
4
4
  [![NPM version](https://img.shields.io/npm/v/cron-converter-u2q)](https://www.npmjs.com/package/cron-converter-u2q)
5
- ![GitHub License](https://img.shields.io/github/license/rahu619/cron-converter-u2q?style=plastic)
6
- ![GitHub Build](https://github.com/rahu619/cron-converter-u2q/actions/workflows/integration.yml/badge.svg?branch=main)
7
- ![Github Release](https://github.com/rahu619/cron-converter-u2q/actions/workflows/release.yml/badge.svg?event=workflow_dispatch)
8
- ![Github Top Language](https://img.shields.io/github/languages/top/rahu619/cron-converter-u2q?style=plastic)
5
+ [![GitHub License](https://img.shields.io/github/license/rahu619/cron-converter-u2q?style=plastic)](LICENSE)
6
+ [![GitHub Build](https://github.com/rahu619/cron-converter-u2q/actions/workflows/integration.yml/badge.svg?branch=main)](https://github.com/rahu619/cron-converter-u2q/actions)
7
+ [![Github Release](https://github.com/rahu619/cron-converter-u2q/actions/workflows/release.yml/badge.svg?event=workflow_dispatch)](https://github.com/rahu619/cron-converter-u2q/actions)
8
+ [![Github Top Language](https://img.shields.io/github/languages/top/rahu619/cron-converter-u2q?style=plastic)](https://www.typescriptlang.org/)
9
+ [![npm downloads](https://img.shields.io/npm/dm/cron-converter-u2q)](https://www.npmjs.com/package/cron-converter-u2q)
9
10
 
10
11
  [![https://nodei.co/npm/cron-converter-u2q.png?downloads=true&downloadRank=true&stars=true](https://nodei.co/npm/cron-converter-u2q.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/cron-converter-u2q)
11
12
 
12
- Easily work with cron expressions using the `cron-converter-u2q` package. Effortlessly convert between Unix and Quartz formats and describe cron schedules in plain language.
13
+ A powerful TypeScript library for working with cron expressions. Effortlessly convert between Unix and Quartz formats, generate human-readable descriptions, and validate cron expressions with ease.
13
14
 
14
- ### Features
15
+ ## Features
15
16
 
16
- :arrows_counterclockwise: **Two-way conversion**
17
+ ### 🔄 Two-way Conversion
18
+ - **Unix to Quartz**: Convert standard Unix cron expressions to Quartz format
19
+ - **Quartz to Unix**: Convert Quartz cron expressions to standard Unix format
20
+ - **Format Validation**: Built-in validation for both formats
21
+ - **Error Handling**: Clear error messages for invalid expressions
17
22
 
18
- Effortlessly convert cron expressions:
19
- - From Unix to Quartz
20
- - From Quartz to Unix
23
+ ### 📝 Human-readable Descriptions
24
+ - **Natural Language**: Convert cron expressions to plain English
25
+ - **Multiple Languages**: Support for different language descriptions
26
+ - **Customizable**: Extend with your own description templates
27
+ - **Detailed**: Includes all schedule details (minutes, hours, days, etc.)
21
28
 
22
- :memo: **Human-readable Descriptions**
29
+ ### 🛠️ Developer Friendly
30
+ - **TypeScript Support**: Full type definitions included
31
+ - **Zero Dependencies**: Lightweight and fast
32
+ - **Well Tested**: Comprehensive test coverage
33
+ - **ES6 Modules**: Support for both CommonJS and ES6 imports
23
34
 
24
- Translate cron schedules into plain, understandable text:
25
- - Example: `*/5 * * * *` -> "Every 5 minutes"
35
+ ### 🔍 Validation & Error Handling
36
+ - **Format Validation**: Ensures cron expressions are valid
37
+ - **Range Checking**: Validates field values within acceptable ranges
38
+ - **Clear Errors**: Descriptive error messages for debugging
39
+ - **Type Safety**: TypeScript types for better development experience
26
40
 
27
- ### Installation
28
-
29
- Using npm:
41
+ ## 📦 Installation
30
42
 
31
43
  ```bash
44
+ # Using npm
32
45
  npm install cron-converter-u2q
33
- ```
34
-
35
- Using yarn:
36
46
 
37
- ```bash
47
+ # Using yarn
38
48
  yarn add cron-converter-u2q
49
+
50
+ # Using pnpm
51
+ pnpm add cron-converter-u2q
39
52
  ```
40
53
 
41
- ### Usage
54
+ ## 🚀 Quick Start
42
55
 
43
- Firstly, import the CronConverterU2Q module:
56
+ ```typescript
57
+ import { CronConverterU2Q, CronDescriberU2Q } from 'cron-converter-u2q';
44
58
 
45
- ```javascript
46
- var cron_converter_u2q = require("cron-converter-u2q");
59
+ // Convert Unix to Quartz
60
+ const quartzExpression = CronConverterU2Q.unixToQuartz('5 * * * *');
61
+ console.log(quartzExpression); // "0 5 * * * ? *"
47
62
 
48
- var c2q = cron_converter_u2q.CronConverterU2Q;
63
+ // Convert Quartz to Unix
64
+ const unixExpression = CronConverterU2Q.quartzToUnix('0 0 8 * * ?');
65
+ console.log(unixExpression); // "0 8 * * *"
66
+ // Get human-readable description
67
+ const description = CronDescriberU2Q.describeUnix('*/5 * * * *');
68
+ console.log(description); // "Every 5 minutes"
49
69
  ```
50
70
 
51
- If you're using ES6 Modules
71
+ ## 📚 Examples
52
72
 
53
- ```javascript
54
- import { CronConverterU2QModule as c2q } from "cron-converter-u2q";
73
+ ### Basic Conversions
74
+
75
+ ```typescript
76
+ // Unix to Quartz
77
+ CronConverterU2Q.unixToQuartz('0 12 * * *'); // "0 0 12 * * ? *"
78
+ CronConverterU2Q.unixToQuartz('*/15 * * * *'); // "0 */15 * * * ? *"
79
+ // Quartz to Unix
80
+ CronConverterU2Q.quartzToUnix('0 0 8 * * ?'); // "0 8 * * *"
81
+ CronConverterU2Q.quartzToUnix('0 */5 * * * ?'); // "*/5 * * * *"
55
82
  ```
56
83
 
57
- ### Conversion Methods
84
+ ### Human-readable Descriptions
58
85
 
59
- #### Convert from Unix to Quartz:
86
+ ```typescript
87
+ // Unix format descriptions
88
+ CronDescriberU2Q.describeUnix('0 12 * * *'); // "At 12 o'clock"
89
+ CronDescriberU2Q.describeUnix('*/15 * * * *'); // "Every 15 minutes"
60
90
 
61
- ```javascript
62
- const quartzExpression = c2q.unixToQuartz("5 * * * *");
91
+ // Quartz format descriptions
92
+ CronDescriberU2Q.describeQuartz('0 0 8 * * ?'); // "At 8 o'clock"
93
+ CronDescriberU2Q.describeQuartz('0 */5 * * * ?'); // "Every 5 minutes"
63
94
  ```
64
95
 
65
- #### Convert from Quartz to Unix:
96
+ ## 🤝 Contributing
66
97
 
67
- ```javascript
68
- const unixExpression = c2q.quartzToUnix("* */5 * ? * * *");
69
- ```
98
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
70
99
 
71
- ### Description Methods
100
+ 1. Fork the repository
101
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
102
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
103
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
104
+ 5. Open a Pull Request
72
105
 
73
- You can now generate human-readable descriptions for Unix and Quartz cron expressions.
106
+ ## 📄 License
74
107
 
75
- #### Describe Unix Cron Expressions:
108
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
76
109
 
77
- ```javascript
78
- const description = c2q.describeUnix("5 * * * *");
79
- console.log(description); // Outputs: "Every 5 minutes"
80
- ```
110
+ ## 💬 Support
81
111
 
82
- #### Describe Quartz Cron Expressions:
112
+ - 📧 Email: rahu619@gmail.com
113
+ - 💻 GitHub Issues: [Create an issue](https://github.com/rahu619/cron-converter-u2q/issues)
114
+ - ⭐ Star the repository if you find it useful!
83
115
 
84
- ```javascript
85
- const description = c2q.describeQuartz("0 0 8 * * ?");
86
- console.log(description); // Outputs: "At 8 o'clock"
87
- ```
116
+ ## 🙏 Acknowledgments
88
117
 
89
- ## License
90
- This project is licensed under the [MIT License](https://opensource.org/license/mit/)
118
+ - Thanks to all contributors who have helped shape this project
119
+ - Inspired by the need for a simple, reliable cron expression converter
120
+ - Built with TypeScript for better developer experience
91
121
 
122
+ ## 📖 Specifications
92
123
 
93
- ### Contributing
94
- Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
124
+ This library's conversion logic is grounded in the following official specifications:
95
125
 
96
- Please make sure to update tests as appropriate.
126
+ - **POSIX IEEE Std 1003.1** Defines the standard Unix cron expression format (5 fields: minute, hour, day-of-month, month, day-of-week).
127
+ [https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html)
97
128
 
98
- ### Support
99
- Any feedback, suggestions, or contributions are highly appreciated!
129
+ - **Quartz Scheduler** – Defines the extended Quartz cron trigger format (6–7 fields: seconds, minute, hour, day-of-month, month, day-of-week, optional year). Notably, exactly one of `day-of-month` or `day-of-week` must be `?` to avoid scheduling conflicts.
130
+ [https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html)
100
131
 
@@ -1,7 +1,4 @@
1
1
  export declare class CronConverterU2Q {
2
- static readonly delimiter = " ";
3
- static readonly unixExpressionLength = 5;
4
- static readonly quartzExpressionLengths: number[];
5
2
  /**
6
3
  * Converts a unix cron expression to a quartz cron expression by adding '0' seconds
7
4
  * @param unixExpression - the unix expression
@@ -14,5 +11,21 @@ export declare class CronConverterU2Q {
14
11
  * @returns the corresponding unix expression
15
12
  */
16
13
  static quartzToUnix(quartzExpression: string): string;
17
- private static validateIfNullOrEmpty;
14
+ /**
15
+ * Converts interval parts for both Unix and Quartz expressions.
16
+ * In both directions, normalises step notation to the Unix `*\/N` format.
17
+ */
18
+ private static convertIntervalParts;
19
+ /**
20
+ * Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
21
+ * Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
22
+ * Quartz: 1=Sun, 2=Mon, ..., 7=Sat
23
+ */
24
+ private static unixDowToQuartz;
25
+ /**
26
+ * Converts Quartz DOW to Unix DOW, supporting lists, ranges, and special cases.
27
+ * Quartz: 1=Sun, 2=Mon, ..., 7=Sat
28
+ * Unix: 0=Sun, 1=Mon, ..., 6=Sat
29
+ */
30
+ static quartzDowToUnix(dow: string): string;
18
31
  }
package/lib/converter.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CronConverterU2Q = void 0;
4
+ const helper_1 = require("./helper");
5
+ const validator_1 = require("./validator");
4
6
  class CronConverterU2Q {
5
7
  /**
6
8
  * Converts a unix cron expression to a quartz cron expression by adding '0' seconds
@@ -8,18 +10,21 @@ class CronConverterU2Q {
8
10
  * @returns the corresponding quartz expression
9
11
  */
10
12
  static unixToQuartz(unixExpression) {
11
- this.validateIfNullOrEmpty(unixExpression);
12
- const parts = unixExpression.split(this.delimiter);
13
- if (parts.length !== this.unixExpressionLength)
14
- throw new Error(`Invalid unix cron format`);
15
- const [min, hour, dom, month, dow] = parts;
13
+ validator_1.CronValidatorU2Q.validateUnix(unixExpression);
14
+ const parts = helper_1.ExpressionHelper.GetExpressionParts(unixExpression);
15
+ const [min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part));
16
+ // Enhanced DOW conversion: handle lists, ranges, and special cases
17
+ let quartzDow = this.unixDowToQuartz(dow);
16
18
  let quartzDom = dom;
17
- let quartzDow = dow;
18
- if (dom === '*' && (dow === '*' || dow !== '*'))
19
+ // Per Quartz spec, exactly one of DOM or DOW must be '?'
20
+ // When DOM is '*' and DOW is specific, DOM gets '?'; otherwise DOW gets '?'
21
+ if (dom === '*' && dow !== '*') {
19
22
  quartzDom = '?';
20
- else if (dom !== '*' && dow === '*')
23
+ }
24
+ else if (dom !== '*' && dow === '*') {
21
25
  quartzDow = '?';
22
- return `0 ${min} ${hour} ${quartzDom} ${month} ${quartzDow}`;
26
+ }
27
+ return `0 ${min} ${hour} ${quartzDom} ${month} ${quartzDow} *`;
23
28
  }
24
29
  /**
25
30
  * Converts a quartz cron expression to a unix cron expression
@@ -27,27 +32,87 @@ class CronConverterU2Q {
27
32
  * @returns the corresponding unix expression
28
33
  */
29
34
  static quartzToUnix(quartzExpression) {
30
- this.validateIfNullOrEmpty(quartzExpression);
31
- const parts = quartzExpression.split(this.delimiter);
32
- if (!this.quartzExpressionLengths.includes(parts.length))
33
- throw new Error(`Invalid quartz cron format`);
34
- const [_, min, hour, dom, month, dow] = parts;
35
- let unixDom = dom;
36
- let unixDow = dow;
37
- if (dom === '?' && dow === '*')
38
- unixDom = '*';
39
- else if (dow === '?' && dom === '*')
40
- unixDow = '*';
41
- else if (dom !== '?' && dom === '?')
42
- unixDom = '*';
35
+ validator_1.CronValidatorU2Q.validateQuartz(quartzExpression);
36
+ const parts = helper_1.ExpressionHelper.GetExpressionParts(quartzExpression);
37
+ const [_, min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part, true));
38
+ if (dom.includes('L') || dom.includes('W')) {
39
+ throw new Error("Unix cron does not support 'L' or 'W' in Day of Month");
40
+ }
41
+ if (dow.includes('L') || dow.includes('#')) {
42
+ throw new Error("Unix cron does not support 'L' or '#' in Day of Week");
43
+ }
44
+ // Enhanced DOW conversion: handle lists, ranges, and special cases
45
+ let unixDow = this.quartzDowToUnix(dow);
46
+ let unixDom = dom === '?' ? '*' : dom;
43
47
  return `${min} ${hour} ${unixDom} ${month} ${unixDow}`;
44
48
  }
45
- static validateIfNullOrEmpty(cronExpression) {
46
- if (!cronExpression || cronExpression.trim() === '')
47
- throw new Error('Empty or null expression');
49
+ /**
50
+ * Converts interval parts for both Unix and Quartz expressions.
51
+ * In both directions, normalises step notation to the Unix `*\/N` format.
52
+ */
53
+ static convertIntervalParts(part, isQuartz = false) {
54
+ if (isQuartz) {
55
+ return part.replace(/^0\/(\d+)$/, '*/$1');
56
+ }
57
+ return part;
58
+ }
59
+ /**
60
+ * Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
61
+ * Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
62
+ * Quartz: 1=Sun, 2=Mon, ..., 7=Sat
63
+ */
64
+ static unixDowToQuartz(dow) {
65
+ if (dow === '*' || dow === '?')
66
+ return dow;
67
+ if (dow.includes(','))
68
+ return dow.split(',').map(d => this.unixDowToQuartz(d)).join(',');
69
+ if (dow.includes('-'))
70
+ return dow.split('-').map(d => this.unixDowToQuartz(d)).join('-');
71
+ if (dow.endsWith('L')) {
72
+ const day = dow.slice(0, -1);
73
+ return `${this.unixDowToQuartz(day)}L`;
74
+ }
75
+ if (dow.includes('#')) {
76
+ const [day, nth] = dow.split('#');
77
+ return `${this.unixDowToQuartz(day)}#${nth}`;
78
+ }
79
+ if (dow === '0' || dow === '7')
80
+ return '1'; // Sunday
81
+ const num = parseInt(dow, 10);
82
+ if (!isNaN(num) && num >= 1 && num <= 6)
83
+ return (num + 1).toString(); // Mon(1)→2 … Sat(6)→7
84
+ return dow;
85
+ }
86
+ /**
87
+ * Converts Quartz DOW to Unix DOW, supporting lists, ranges, and special cases.
88
+ * Quartz: 1=Sun, 2=Mon, ..., 7=Sat
89
+ * Unix: 0=Sun, 1=Mon, ..., 6=Sat
90
+ */
91
+ static quartzDowToUnix(dow) {
92
+ if (dow === '*' || dow === '?')
93
+ return dow === '?' ? '*' : dow;
94
+ // Split compound expressions so each element is converted individually
95
+ if (dow.includes(','))
96
+ return dow.split(',').map(d => this.quartzDowToUnix(d)).join(',');
97
+ if (dow.includes('-'))
98
+ return dow.split('-').map(d => this.quartzDowToUnix(d)).join('-');
99
+ // Last (L) — convert the numeric day part, preserve L suffix
100
+ if (dow.endsWith('L')) {
101
+ const day = dow.slice(0, -1);
102
+ return `${this.quartzDowToUnix(day)}L`;
103
+ }
104
+ // Nth weekday (#) — convert the numeric day part, preserve #N
105
+ if (dow.includes('#')) {
106
+ const [day, nth] = dow.split('#');
107
+ return `${this.quartzDowToUnix(day)}#${nth}`;
108
+ }
109
+ // Numeric mapping
110
+ if (dow === '1')
111
+ return '0'; // Sunday
112
+ const num = parseInt(dow, 10);
113
+ if (!isNaN(num) && num >= 2 && num <= 7)
114
+ return (num - 1).toString(); // Mon(2)→1 … Sat(7)→6
115
+ return dow;
48
116
  }
49
117
  }
50
118
  exports.CronConverterU2Q = CronConverterU2Q;
51
- CronConverterU2Q.delimiter = ' ';
52
- CronConverterU2Q.unixExpressionLength = 5;
53
- CronConverterU2Q.quartzExpressionLengths = [6, 7];
@@ -0,0 +1,41 @@
1
+ export declare class CronDescriberU2Q {
2
+ /**
3
+ * Generates a human-readable description for a Unix-style cron expression.
4
+ *
5
+ * Unix-style cron expressions consist of 5 parts:
6
+ * - Minute (0-59)
7
+ * - Hour (0-23)
8
+ * - Day of Month (1-31)
9
+ * - Month (1-12)
10
+ * - Day of Week (0-6, where 0 = Sunday)
11
+ * @param unixExpression - A string containing the Unix-style cron expression.
12
+ * @returns A human-readable description or an error message if invalid.
13
+ */
14
+ static describeUnix(unixExpression: string): string;
15
+ /**
16
+ * Generates a human-readable description for a Quartz-style cron expression.
17
+ *
18
+ * Quartz-style cron expressions consist of 6 or 7 parts:
19
+ * - Second (0-59)
20
+ * - Minute (0-59)
21
+ * - Hour (0-23)
22
+ * - Day of Month (1-31)
23
+ * - Month (1-12)
24
+ * - Day of Week (1-7, where 1 = Sunday)
25
+ * - Year (optional)
26
+ * @param quartzExpression - A string containing the Quartz-style cron expression.
27
+ * @returns A human-readable description or an error message if invalid.
28
+ */
29
+ static describeQuartz(quartzExpression: string): string;
30
+ private static describeSecond;
31
+ private static describeMinute;
32
+ private static describeHour;
33
+ private static describeDayOfMonth;
34
+ private static describeMonth;
35
+ private static describeDayOfWeek;
36
+ private static describeYear;
37
+ private static resolveValue;
38
+ private static describeField;
39
+ private static ordinalSuffix;
40
+ private static combineDescriptions;
41
+ }