@@ -84,6 +84,27 @@ type CronStateFile = {
|
84 | 84 | jobs: Record<string, CronStateFileEntry>; |
85 | 85 | }; |
86 | 86 | |
| 87 | +function parseCronStateFile(raw: string): CronStateFile | null { |
| 88 | +try { |
| 89 | +const parsed = parseJsonWithJson5Fallback(raw); |
| 90 | +if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { |
| 91 | +return null; |
| 92 | +} |
| 93 | +const record = parsed as Record<string, unknown>; |
| 94 | +if ( |
| 95 | +record.version !== 1 || |
| 96 | +typeof record.jobs !== "object" || |
| 97 | +record.jobs === null || |
| 98 | +Array.isArray(record.jobs) |
| 99 | +) { |
| 100 | +return null; |
| 101 | +} |
| 102 | +return { version: 1, jobs: record.jobs as Record<string, CronStateFileEntry> }; |
| 103 | +} catch { |
| 104 | +return null; |
| 105 | +} |
| 106 | +} |
| 107 | + |
87 | 108 | function normalizeCronStoreFile(parsed: unknown): CronStoreFile { |
88 | 109 | const rawJobs = getRawCronJobs(parsed); |
89 | 110 | return { |
@@ -153,25 +174,7 @@ async function loadStateFile(statePath: string): Promise<CronStateFile | null> {
|
153 | 174 | }); |
154 | 175 | } |
155 | 176 | |
156 | | -try { |
157 | | -const parsed = parseJsonWithJson5Fallback(raw); |
158 | | -if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { |
159 | | -return null; |
160 | | -} |
161 | | -const record = parsed as Record<string, unknown>; |
162 | | -if ( |
163 | | -record.version !== 1 || |
164 | | -typeof record.jobs !== "object" || |
165 | | -record.jobs === null || |
166 | | -Array.isArray(record.jobs) |
167 | | -) { |
168 | | -return null; |
169 | | -} |
170 | | -return { version: 1, jobs: record.jobs as Record<string, CronStateFileEntry> }; |
171 | | -} catch { |
172 | | -// Best-effort: if state file is corrupt, treat as absent. |
173 | | -return null; |
174 | | -} |
| 177 | +return parseCronStateFile(raw); |
175 | 178 | } |
176 | 179 | |
177 | 180 | function loadStateFileSync(statePath: string): CronStateFile | null { |
@@ -187,24 +190,7 @@ function loadStateFileSync(statePath: string): CronStateFile | null {
|
187 | 190 | }); |
188 | 191 | } |
189 | 192 | |
190 | | -try { |
191 | | -const parsed = parseJsonWithJson5Fallback(raw); |
192 | | -if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { |
193 | | -return null; |
194 | | -} |
195 | | -const record = parsed as Record<string, unknown>; |
196 | | -if ( |
197 | | -record.version !== 1 || |
198 | | -typeof record.jobs !== "object" || |
199 | | -record.jobs === null || |
200 | | -Array.isArray(record.jobs) |
201 | | -) { |
202 | | -return null; |
203 | | -} |
204 | | -return { version: 1, jobs: record.jobs as Record<string, CronStateFileEntry> }; |
205 | | -} catch { |
206 | | -return null; |
207 | | -} |
| 193 | +return parseCronStateFile(raw); |
208 | 194 | } |
209 | 195 | |
210 | 196 | function hasInlineState(jobs: Array<Record<string, unknown> | null | undefined>): boolean { |
|