okf-kit 0.8.0 → 0.10.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/dist/util.js CHANGED
@@ -47,4 +47,76 @@ export function getTimestampEpoch(parsed) {
47
47
  return undefined;
48
48
  return Math.floor(ms / 1000);
49
49
  }
50
+ /**
51
+ * The frontmatter `timestamp`'s raw string form, or undefined when it is
52
+ * absent, blank, or not a string -- notably, a native `Date` instance (see
53
+ * `getTimestampEpoch`'s doc comment) returns undefined here too, since a
54
+ * `Date`'s `getTime()` is always UTC-unambiguous and carries none of the
55
+ * local-timezone risk `hasUtcDesignator` exists to catch. Used only by
56
+ * `sources-fresh-future`'s UTC-designator gate; `sources-fresh` itself has
57
+ * no need for the raw string, only the resolved epoch.
58
+ */
59
+ export function getRawTimestampString(parsed) {
60
+ if (!isRecord(parsed))
61
+ return undefined;
62
+ const timestamp = parsed.timestamp;
63
+ if (typeof timestamp !== "string" || timestamp.trim() === "")
64
+ return undefined;
65
+ return timestamp;
66
+ }
67
+ /**
68
+ * Whether an ISO-ish timestamp string carries an explicit UTC designator
69
+ * (`Z`) or a numeric UTC offset (`+02:00`, `-0500`) at its end. A timestamp
70
+ * with neither ("2026-01-01T00:00:00", "2026-01-01 00:00:00") parses in
71
+ * the machine's LOCAL timezone under `Date.parse`, which would make
72
+ * `sources-fresh-future`'s clock-skew comparison swing by hours depending
73
+ * on which machine runs the check -- not usable for a check whose default
74
+ * allowance is only 10 minutes. A numeric offset, unlike a bare local
75
+ * time, is unambiguous: `Date.parse`/`Date#getTime()` already normalizes
76
+ * it to a real UTC instant, so no extra conversion is needed here beyond
77
+ * recognizing it as present. `sources-fresh`'s own thresholds are in
78
+ * days, wide enough that this ambiguity doesn't practically matter there,
79
+ * so this helper is deliberately NOT applied to that rule's comparison.
80
+ */
81
+ export function hasUtcDesignator(raw) {
82
+ return /(?:Z|[+-]\d{2}:?\d{2})$/i.test(raw.trim());
83
+ }
84
+ /**
85
+ * A canonical identity string for the frontmatter `timestamp` VALUE, or
86
+ * undefined when the key is absent, blank, or not a scalar this tool
87
+ * understands. Two docs (or two revisions of one doc) are "stamped the same"
88
+ * iff this returns the same value for both.
89
+ *
90
+ * Used by `sources-fresh` to decide whether a commit actually re-stamped a
91
+ * doc, by comparing the doc's frontmatter at that commit against its
92
+ * frontmatter in the commit's first parent. Comparing VALUES, not diff text,
93
+ * is what makes the test immune to the three shapes a diff-text scan gets
94
+ * wrong: a `timestamp:` line inside a fenced YAML example in the doc BODY (it
95
+ * is not the frontmatter key, so it never reaches this function at all), a
96
+ * rename (the two revisions are read by path, not from a diff header), and a
97
+ * merge commit (whose combined-diff output is empty while its trees are
98
+ * perfectly readable).
99
+ *
100
+ * The `date:`/`string:` prefixes keep the two YAML shapes distinguishable: a
101
+ * `!!timestamp`-tagged scalar resolving to a native `Date` and a plain string
102
+ * are different frontmatter, so rewriting one into the other counts as a
103
+ * re-stamp rather than silently comparing equal. Deliberately NOT normalized
104
+ * to an epoch: this is an identity test ("did the value change"), not a
105
+ * chronological one, so re-writing `2026-01-01T00:00:00Z` as
106
+ * `2026-01-01T00:00:00+00:00` counts as a re-stamp -- the author touched the
107
+ * stamp. Whether the new value is CORRECT is a separate question this
108
+ * function deliberately does not answer (see the README's known limitations).
109
+ */
110
+ export function getTimestampIdentity(parsed) {
111
+ if (!isRecord(parsed))
112
+ return undefined;
113
+ const timestamp = parsed.timestamp;
114
+ if (timestamp instanceof Date) {
115
+ const ms = timestamp.getTime();
116
+ return Number.isNaN(ms) ? undefined : `date:${ms}`;
117
+ }
118
+ if (typeof timestamp !== "string" || timestamp.trim() === "")
119
+ return undefined;
120
+ return `string:${timestamp.trim()}`;
121
+ }
50
122
  //# sourceMappingURL=util.js.map
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS,IAAI,MAAM,CAAC;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAI,MAAkC,CAAC,OAAO,CAAC;IAC5D,MAAM,YAAY,GAChB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,OAAO,YAAY,CAAC,CAAC,CAAE,OAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,IAAI,SAAS,YAAY,IAAI,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE;QAC1D,OAAO,SAAS,CAAC;IACnB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okf-kit",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "CLI that validates OKF v0.1 knowledge bundles for structural correctness",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "commander": "^12.0.0",
41
- "yaml": "^2.5.0"
41
+ "yaml": "^2.8.3"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^20.11.0",