@things-factory/shell 8.0.55 → 8.0.61
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/dist-server/index.d.ts +1 -0
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/typeorm/cron-month-transform.d.ts +5 -0
- package/dist-server/typeorm/cron-month-transform.js +60 -0
- package/dist-server/typeorm/cron-month-transform.js.map +1 -0
- package/package.json +2 -2
- package/server/index.ts +1 -0
- package/server/typeorm/cron-month-transform.ts +58 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cronMonthZeroBasedTransformer = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 크론 표현식의 월 필드(5필드=분-시-일-월-요일 / 6필드=초-분-시-일-월-요일)만 숫자일 때 ±1 시프트한다.
|
|
6
|
+
* - 리스트(1,3,12), 범위(3-5), 스텝(3/2, 3-9/2)에서 숫자에 한해 변환
|
|
7
|
+
* - 영문(JAN-DEC), '*', '?' 등은 그대로 둔다.
|
|
8
|
+
*/
|
|
9
|
+
function shiftMonthNumbersInCronExpression(expression, delta) {
|
|
10
|
+
if (!expression)
|
|
11
|
+
return expression;
|
|
12
|
+
const parts = expression.trim().split(/\s+/);
|
|
13
|
+
if (parts.length !== 5 && parts.length !== 6)
|
|
14
|
+
return expression;
|
|
15
|
+
const monthIndex = parts.length === 6 ? 4 : 3;
|
|
16
|
+
const monthToken = parts[monthIndex];
|
|
17
|
+
const isNumeric = (s) => /^\d+$/.test(s);
|
|
18
|
+
const isAlpha = (s) => /^[A-Za-z]+$/.test(s);
|
|
19
|
+
const passthrough = (s) => s === '*' || s === '?';
|
|
20
|
+
const shiftNum = (nStr) => (isNumeric(nStr) ? String(parseInt(nStr, 10) + delta) : nStr);
|
|
21
|
+
const shiftPrimary = (primary) => {
|
|
22
|
+
const p = primary.trim();
|
|
23
|
+
if (p.includes('-')) {
|
|
24
|
+
const [a, b] = p.split('-');
|
|
25
|
+
return `${shiftNum(a.trim())}-${shiftNum(b.trim())}`;
|
|
26
|
+
}
|
|
27
|
+
return shiftNum(p);
|
|
28
|
+
};
|
|
29
|
+
const shiftedMonth = monthToken
|
|
30
|
+
.split(',')
|
|
31
|
+
.map(seg => {
|
|
32
|
+
const part = seg.trim();
|
|
33
|
+
if (!part)
|
|
34
|
+
return part;
|
|
35
|
+
if (passthrough(part) || isAlpha(part))
|
|
36
|
+
return part;
|
|
37
|
+
const [primary, step] = part.split('/');
|
|
38
|
+
const shifted = shiftPrimary(primary);
|
|
39
|
+
return step ? `${shifted}/${step}` : shifted;
|
|
40
|
+
})
|
|
41
|
+
.join(',');
|
|
42
|
+
parts[monthIndex] = shiftedMonth;
|
|
43
|
+
return parts.join(' ');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* DB 저장/로드 시 월 숫자만 0-기반↔1-기반으로 상호 변환하는 트랜스포머
|
|
47
|
+
*/
|
|
48
|
+
exports.cronMonthZeroBasedTransformer = {
|
|
49
|
+
to(value) {
|
|
50
|
+
if (value == null)
|
|
51
|
+
return value;
|
|
52
|
+
return shiftMonthNumbersInCronExpression(value, -1);
|
|
53
|
+
},
|
|
54
|
+
from(value) {
|
|
55
|
+
if (value == null)
|
|
56
|
+
return value;
|
|
57
|
+
return shiftMonthNumbersInCronExpression(value, +1);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=cron-month-transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-month-transform.js","sourceRoot":"","sources":["../../server/typeorm/cron-month-transform.ts"],"names":[],"mappings":"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","sourcesContent":["import { ValueTransformer } from 'typeorm'\n\n/**\n * 크론 표현식의 월 필드(5필드=분-시-일-월-요일 / 6필드=초-분-시-일-월-요일)만 숫자일 때 ±1 시프트한다.\n * - 리스트(1,3,12), 범위(3-5), 스텝(3/2, 3-9/2)에서 숫자에 한해 변환\n * - 영문(JAN-DEC), '*', '?' 등은 그대로 둔다.\n */\nfunction shiftMonthNumbersInCronExpression(expression: string, delta: number): string {\n if (!expression) return expression\n const parts = expression.trim().split(/\\s+/)\n if (parts.length !== 5 && parts.length !== 6) return expression\n const monthIndex = parts.length === 6 ? 4 : 3\n const monthToken = parts[monthIndex]\n\n const isNumeric = (s: string) => /^\\d+$/.test(s)\n const isAlpha = (s: string) => /^[A-Za-z]+$/.test(s)\n const passthrough = (s: string) => s === '*' || s === '?'\n\n const shiftNum = (nStr: string) => (isNumeric(nStr) ? String(parseInt(nStr, 10) + delta) : nStr)\n\n const shiftPrimary = (primary: string) => {\n const p = primary.trim()\n if (p.includes('-')) {\n const [a, b] = p.split('-')\n return `${shiftNum(a.trim())}-${shiftNum(b.trim())}`\n }\n return shiftNum(p)\n }\n\n const shiftedMonth = monthToken\n .split(',')\n .map(seg => {\n const part = seg.trim()\n if (!part) return part\n if (passthrough(part) || isAlpha(part)) return part\n const [primary, step] = part.split('/')\n const shifted = shiftPrimary(primary)\n return step ? `${shifted}/${step}` : shifted\n })\n .join(',')\n\n parts[monthIndex] = shiftedMonth\n return parts.join(' ')\n}\n\n/**\n * DB 저장/로드 시 월 숫자만 0-기반↔1-기반으로 상호 변환하는 트랜스포머\n */\nexport const cronMonthZeroBasedTransformer: ValueTransformer = {\n to(value: string | null | undefined) {\n if (value == null) return value as any\n return shiftMonthNumbersInCronExpression(value, -1)\n },\n from(value: string | null | undefined) {\n if (value == null) return value as any\n return shiftMonthNumbersInCronExpression(value, +1)\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/shell",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.61",
|
|
4
4
|
"description": "Core module for framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"things-factory": "bin/things-factory",
|
|
@@ -134,5 +134,5 @@
|
|
|
134
134
|
"pg": "^8.7.3",
|
|
135
135
|
"sqlite3": "^5.0.8"
|
|
136
136
|
},
|
|
137
|
-
"gitHead": "
|
|
137
|
+
"gitHead": "72a14cc70333dcba45b4c1a6ca8140a8dc1c87a5"
|
|
138
138
|
}
|
package/server/index.ts
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ValueTransformer } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 크론 표현식의 월 필드(5필드=분-시-일-월-요일 / 6필드=초-분-시-일-월-요일)만 숫자일 때 ±1 시프트한다.
|
|
5
|
+
* - 리스트(1,3,12), 범위(3-5), 스텝(3/2, 3-9/2)에서 숫자에 한해 변환
|
|
6
|
+
* - 영문(JAN-DEC), '*', '?' 등은 그대로 둔다.
|
|
7
|
+
*/
|
|
8
|
+
function shiftMonthNumbersInCronExpression(expression: string, delta: number): string {
|
|
9
|
+
if (!expression) return expression
|
|
10
|
+
const parts = expression.trim().split(/\s+/)
|
|
11
|
+
if (parts.length !== 5 && parts.length !== 6) return expression
|
|
12
|
+
const monthIndex = parts.length === 6 ? 4 : 3
|
|
13
|
+
const monthToken = parts[monthIndex]
|
|
14
|
+
|
|
15
|
+
const isNumeric = (s: string) => /^\d+$/.test(s)
|
|
16
|
+
const isAlpha = (s: string) => /^[A-Za-z]+$/.test(s)
|
|
17
|
+
const passthrough = (s: string) => s === '*' || s === '?'
|
|
18
|
+
|
|
19
|
+
const shiftNum = (nStr: string) => (isNumeric(nStr) ? String(parseInt(nStr, 10) + delta) : nStr)
|
|
20
|
+
|
|
21
|
+
const shiftPrimary = (primary: string) => {
|
|
22
|
+
const p = primary.trim()
|
|
23
|
+
if (p.includes('-')) {
|
|
24
|
+
const [a, b] = p.split('-')
|
|
25
|
+
return `${shiftNum(a.trim())}-${shiftNum(b.trim())}`
|
|
26
|
+
}
|
|
27
|
+
return shiftNum(p)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const shiftedMonth = monthToken
|
|
31
|
+
.split(',')
|
|
32
|
+
.map(seg => {
|
|
33
|
+
const part = seg.trim()
|
|
34
|
+
if (!part) return part
|
|
35
|
+
if (passthrough(part) || isAlpha(part)) return part
|
|
36
|
+
const [primary, step] = part.split('/')
|
|
37
|
+
const shifted = shiftPrimary(primary)
|
|
38
|
+
return step ? `${shifted}/${step}` : shifted
|
|
39
|
+
})
|
|
40
|
+
.join(',')
|
|
41
|
+
|
|
42
|
+
parts[monthIndex] = shiftedMonth
|
|
43
|
+
return parts.join(' ')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* DB 저장/로드 시 월 숫자만 0-기반↔1-기반으로 상호 변환하는 트랜스포머
|
|
48
|
+
*/
|
|
49
|
+
export const cronMonthZeroBasedTransformer: ValueTransformer = {
|
|
50
|
+
to(value: string | null | undefined) {
|
|
51
|
+
if (value == null) return value as any
|
|
52
|
+
return shiftMonthNumbersInCronExpression(value, -1)
|
|
53
|
+
},
|
|
54
|
+
from(value: string | null | undefined) {
|
|
55
|
+
if (value == null) return value as any
|
|
56
|
+
return shiftMonthNumbersInCronExpression(value, +1)
|
|
57
|
+
}
|
|
58
|
+
}
|