@skyhook-io/k8s-ui 1.5.6 → 1.5.8

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.
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { parseGoTimeString } from './parse-go-time'
3
+
4
+ describe('parseGoTimeString', () => {
5
+ it('parses Go default time format (no fractional seconds)', () => {
6
+ expect(parseGoTimeString('2026-07-27 08:27:41 +0000 UTC').toISOString()).toBe(
7
+ '2026-07-27T08:27:41.000Z',
8
+ )
9
+ })
10
+
11
+ it('truncates Go nanosecond precision to milliseconds', () => {
12
+ expect(
13
+ parseGoTimeString('2026-07-27 08:27:41.123456789 +0000 UTC').toISOString(),
14
+ ).toBe('2026-07-27T08:27:41.123Z')
15
+ })
16
+
17
+ it('pads fractional seconds to 3 digits (Go strips trailing zeros)', () => {
18
+ // Go emits ".1" / ".12" when nanoseconds end in zeros; without padding
19
+ // the constructed ISO string violates the .sss profile and Safari rejects
20
+ // it, re-introducing the bug for certs that happen to expire on these
21
+ // round nanoseconds.
22
+ expect(parseGoTimeString('2026-07-27 08:27:41.1 +0000 UTC').toISOString()).toBe(
23
+ '2026-07-27T08:27:41.100Z',
24
+ )
25
+ expect(parseGoTimeString('2026-07-27 08:27:41.12 +0000 UTC').toISOString()).toBe(
26
+ '2026-07-27T08:27:41.120Z',
27
+ )
28
+ expect(parseGoTimeString('2026-07-27 08:27:41.5 +0000 UTC').toISOString()).toBe(
29
+ '2026-07-27T08:27:41.500Z',
30
+ )
31
+ })
32
+
33
+ it('handles non-UTC offsets and ignores tz abbreviation', () => {
34
+ expect(parseGoTimeString('2026-07-27 08:27:41 -0700 PDT').toISOString()).toBe(
35
+ '2026-07-27T15:27:41.000Z',
36
+ )
37
+ })
38
+
39
+ it('falls back to native parser for ISO 8601', () => {
40
+ expect(parseGoTimeString('2026-07-27T08:27:41Z').toISOString()).toBe(
41
+ '2026-07-27T08:27:41.000Z',
42
+ )
43
+ })
44
+
45
+ it('returns Invalid Date for unparseable input', () => {
46
+ expect(isNaN(parseGoTimeString('not a date').getTime())).toBe(true)
47
+ })
48
+
49
+ it('regex normalizes nanosecond inputs without overflow into seconds', () => {
50
+ const d = parseGoTimeString('2026-07-27 08:27:41.999999999 +0000 UTC')
51
+ expect(d.getUTCMilliseconds()).toBe(999)
52
+ expect(d.getUTCSeconds()).toBe(41)
53
+ })
54
+ })
@@ -0,0 +1,23 @@
1
+ // Some Kubernetes controllers serialize timestamps using Go's default
2
+ // `time.Time.String()` format (e.g. "2026-07-27 08:27:41.123456789 +0000 UTC")
3
+ // when the field is typed as `string` instead of `metav1.Time`. ECMAScript
4
+ // only requires `Date(...)` to parse the ISO 8601 subset, so Safari rejects
5
+ // this format while V8 (Chrome/Node) accepts it leniently — which makes the
6
+ // bug invisible in test runners. Known affected schema: CloudNativePG
7
+ // `Cluster.status.certificates.expirations`.
8
+
9
+ const GO_TIME_PATTERN =
10
+ /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})(\.\d+)?\s+([+-]\d{2})(\d{2})\b/
11
+
12
+ export function parseGoTimeString(s: string): Date {
13
+ const m = s.match(GO_TIME_PATTERN)
14
+ if (m) {
15
+ const [, date, time, frac, tzHour, tzMin] = m
16
+ // Go's ".999999999" format strips trailing zeros, so nanos=100_000_000
17
+ // emits ".1". The ISO 8601 simplified profile requires exactly ".sss";
18
+ // pad to 3 digits before truncating so Safari accepts the result.
19
+ const ms = frac ? '.' + (frac.slice(1) + '000').slice(0, 3) : ''
20
+ return new Date(`${date}T${time}${ms}${tzHour}:${tzMin}`)
21
+ }
22
+ return new Date(s)
23
+ }