@chronicle.app/schema 0.2.0 → 0.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/README.md +80 -19
- package/chronicle.ttl +848 -172
- package/dist/datetime.d.ts +10 -0
- package/dist/datetime.js +49 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/schema.d.ts +593 -27
- package/dist/schema.js +2232 -196
- package/package.json +3 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Whether `value` is a full instant in UTC, such as `2024-03-02T14:05:00Z`. */
|
|
2
|
+
export declare function isInstant(value: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Whether `value` is a :DateTime string: a full instant in UTC
|
|
5
|
+
* (`2024-03-02T14:05:00Z`), or a date at year, month, or day precision that
|
|
6
|
+
* may leave trailing year digits, the month, or the day unspecified with `X`
|
|
7
|
+
* and may end in one qualifier (`?` uncertain, `~` approximate, `%` both).
|
|
8
|
+
*/
|
|
9
|
+
export declare function isDateTime(value: string): boolean;
|
|
10
|
+
//# sourceMappingURL=datetime.d.ts.map
|
package/dist/datetime.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// A :DateTime string is one point in time, written in a subset of EDTF
|
|
2
|
+
// (ISO 8601-2). See the :DateTime comment in chronicle.ttl for the forms.
|
|
3
|
+
// A year with any trailing digits unspecified: 1987, 198X, 19XX, 1XXX, XXXX.
|
|
4
|
+
const YEAR = String.raw `\d{4}|\d{3}X|\d{2}XX|\dXXX|XXXX`;
|
|
5
|
+
const DATE = new RegExp(String.raw `^(?<year>${YEAR})(?:-(?<month>\d{2}|XX)(?:-(?<day>\d{2}|XX))?)?(?<qualifier>[?~%])?$`);
|
|
6
|
+
const INSTANT = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(?:\.\d+)?Z$/;
|
|
7
|
+
const daysIn = (year, month) => new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
8
|
+
const validDay = (year, month, day) => {
|
|
9
|
+
if (month === 'XX' || day === 'XX')
|
|
10
|
+
return true;
|
|
11
|
+
const days = /X/.test(year) ? daysIn(2000, Number(month)) : daysIn(Number(year), Number(month));
|
|
12
|
+
return Number(day) >= 1 && Number(day) <= days;
|
|
13
|
+
};
|
|
14
|
+
/** Whether `value` is a full instant in UTC, such as `2024-03-02T14:05:00Z`. */
|
|
15
|
+
export function isInstant(value) {
|
|
16
|
+
const instant = INSTANT.exec(value)?.groups;
|
|
17
|
+
if (!instant)
|
|
18
|
+
return false;
|
|
19
|
+
const { year, month, day, hour, minute, second } = instant;
|
|
20
|
+
return (Number(month) >= 1 &&
|
|
21
|
+
Number(month) <= 12 &&
|
|
22
|
+
validDay(year, month, day) &&
|
|
23
|
+
Number(hour) <= 23 &&
|
|
24
|
+
Number(minute) <= 59 &&
|
|
25
|
+
Number(second) <= 59);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether `value` is a :DateTime string: a full instant in UTC
|
|
29
|
+
* (`2024-03-02T14:05:00Z`), or a date at year, month, or day precision that
|
|
30
|
+
* may leave trailing year digits, the month, or the day unspecified with `X`
|
|
31
|
+
* and may end in one qualifier (`?` uncertain, `~` approximate, `%` both).
|
|
32
|
+
*/
|
|
33
|
+
export function isDateTime(value) {
|
|
34
|
+
if (INSTANT.test(value))
|
|
35
|
+
return isInstant(value);
|
|
36
|
+
const date = DATE.exec(value)?.groups;
|
|
37
|
+
if (!date)
|
|
38
|
+
return false;
|
|
39
|
+
const { year, month, day } = date;
|
|
40
|
+
// An unspecified month with a known day says nothing usable; neither does
|
|
41
|
+
// a value with no known digit at all.
|
|
42
|
+
if (month === 'XX' && day !== undefined && day !== 'XX')
|
|
43
|
+
return false;
|
|
44
|
+
if (year === 'XXXX' && (month === undefined || month === 'XX'))
|
|
45
|
+
return false;
|
|
46
|
+
if (month === undefined || month === 'XX')
|
|
47
|
+
return true;
|
|
48
|
+
return (Number(month) >= 1 && Number(month) <= 12 && (day === undefined || validDay(year, month, day)));
|
|
49
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED