@brandon_m_behring/book-scaffold-astro 3.2.0 → 3.4.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/LATEX_TO_MDX_MAPPING.md +130 -0
- package/dist/index.d.ts +70 -123
- package/dist/index.mjs +372 -138
- package/dist/schemas.d.ts +36 -2
- package/dist/schemas.mjs +183 -52
- package/package.json +3 -2
- package/pages/frontmatter/[...slug].astro +48 -0
- package/pages/print.astro +9 -1
- package/recipes/12-where-to-file-issues.md +58 -0
- package/scripts/build-bib.mjs +18 -0
- package/scripts/build-figures.mjs +19 -0
- package/scripts/build-labels.mjs +20 -0
- package/scripts/render-notebooks.mjs +19 -0
- package/scripts/validate.mjs +51 -37
- package/src/lib/freshness.ts +19 -4
package/src/lib/freshness.ts
CHANGED
|
@@ -49,12 +49,22 @@ const MS_PER_DAY = 1000 * 60 * 60 * 24;
|
|
|
49
49
|
* Compute freshness for a chapter given its last_verified date + volatility.
|
|
50
50
|
*
|
|
51
51
|
* Pure function; caller supplies `now` only in tests. Production callers omit.
|
|
52
|
+
*
|
|
53
|
+
* v3.3.0 (closes issue #1): tolerant of `lastVerified === undefined`. Returns
|
|
54
|
+
* `null` instead of crashing when the chapter schema omits the field (e.g.,
|
|
55
|
+
* academic profile chapters that don't track verification dates, or consumer
|
|
56
|
+
* schemas that don't declare last_verified).
|
|
57
|
+
*
|
|
58
|
+
* Callers compose with optional chaining:
|
|
59
|
+
* const status = getFreshness(d.last_verified, d.volatility)?.status;
|
|
52
60
|
*/
|
|
53
61
|
export function getFreshness(
|
|
54
|
-
lastVerified: Date,
|
|
62
|
+
lastVerified: Date | undefined,
|
|
55
63
|
volatility: VolatilityLevel,
|
|
56
64
|
now: Date = new Date(),
|
|
57
|
-
): Freshness {
|
|
65
|
+
): Freshness | null {
|
|
66
|
+
if (!(lastVerified instanceof Date)) return null;
|
|
67
|
+
|
|
58
68
|
const thresholdDays = THRESHOLDS[volatility];
|
|
59
69
|
const daysOld = Math.floor((now.getTime() - lastVerified.getTime()) / MS_PER_DAY);
|
|
60
70
|
const daysUntil = thresholdDays - daysOld;
|
|
@@ -71,8 +81,13 @@ export function getFreshness(
|
|
|
71
81
|
return { status, daysOld, thresholdDays, daysUntil };
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
/** Human-readable label for each status; used for ARIA + tooltips.
|
|
75
|
-
|
|
84
|
+
/** Human-readable label for each status; used for ARIA + tooltips.
|
|
85
|
+
*
|
|
86
|
+
* v3.3.0: accepts `null` (the new return shape of getFreshness for undefined
|
|
87
|
+
* inputs). Returns a sentinel "unknown" label so callers can render a neutral
|
|
88
|
+
* affordance without a separate branch. */
|
|
89
|
+
export function freshnessLabel(f: Freshness | null): string {
|
|
90
|
+
if (f === null) return 'Verification status unknown';
|
|
76
91
|
switch (f.status) {
|
|
77
92
|
case 'fresh':
|
|
78
93
|
return `Fresh (${f.daysOld}d old; verify within ${f.daysUntil}d)`;
|