@@ -21,9 +21,17 @@ const regDate = /^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])_/
21
21
// - underscore
22
22
const regPrefix = / ^ \d { 8 } _ \d { 2 } _ /
23
23
24
- // Correct date + prefix and filename snake cased
24
+ // Full migration name format:
25
+ // - YYYYMMDD_NN_
26
+ // - then any filename-safe characters (no slashes)
25
27
const regFull = / ^ (?: \d { 4 } ) (?: 0 [ 1 - 9 ] | 1 [ 0 - 2 ] ) (?: 0 [ 1 - 9 ] | [ 1 2 ] \d | 3 [ 0 1 ] ) _ \d { 2 } _ [ ^ \\ / ] + $ /
26
28
29
+ // Date validity check using JS Date
30
+ function isValidDate ( year , month , day ) {
31
+ const d = new Date ( year , month - 1 , day )
32
+ return d . getFullYear ( ) === year && d . getMonth ( ) === month - 1 && d . getDate ( ) === day
33
+ }
34
+
27
35
const MIGRATIONS_PATH = './src/server/db/migrations'
28
36
const dirPath = path . join ( process . cwd ( ) , MIGRATIONS_PATH )
29
37
const files = fs . readdirSync ( dirPath )
@@ -35,10 +43,21 @@ for (const file of files) {
35
43
errors . push ( `${ FgRed } ${ Bright } ✗${ Reset } ${ file } ${ FgYellow } → must start with YYYYMMDD_NN_${ Reset } ` )
36
44
continue
37
45
}
38
- if ( ! regDate . test ( file ) ) {
46
+
47
+ const match = file . match ( regDate )
48
+ if ( ! match ) {
39
49
errors . push ( `${ FgRed } ${ Bright } ✗${ Reset } ${ file } ${ FgYellow } → invalid date format${ Reset } ` )
40
50
continue
51
+ } else {
52
+ const year = parseInt ( match [ 1 ] , 10 )
53
+ const month = parseInt ( match [ 2 ] , 10 )
54
+ const day = parseInt ( match [ 3 ] , 10 )
55
+ if ( ! isValidDate ( year , month , day ) ) {
56
+ errors . push ( `${ FgRed } ${ Bright } ✗${ Reset } ${ file } ${ FgYellow } → impossible calendar date${ Reset } ` )
57
+ continue
58
+ }
41
59
}
60
+
42
61
if ( ! regFull . test ( file ) ) {
43
62
errors . push ( `${ FgRed } ${ Bright } ✗${ Reset } ${ file } ${ FgYellow } → contains invalid characters${ Reset } ` )
44
63
}
0 commit comments